3 * Copyright 2007 Google Inc.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * PHP Unit tests for the CloudStorageTools.
21 namespace google\appengine\api\cloud_storage
;
23 require_once 'google/appengine/api/cloud_storage/CloudStorageTools.php';
24 require_once 'google/appengine/testing/ApiProxyTestBase.php';
26 use google\appengine\testing\ApiProxyTestBase
;
27 use google\appengine\BlobstoreServiceError
;
28 use google\appengine\ImagesServiceError
;
30 // Provide a mock ini_get as we cannot alter the value of upload_max_filesize
32 function ini_get($key) {
33 if ($key === 'upload_max_filesize') {
34 return CloudStorageToolsTest
::$mock_upload_max_filesize;
36 return \
ini_get($key);
40 * Unit test for CloudStorageTools class.
42 * @outputBuffering disabled
44 class CloudStorageToolsTest
extends ApiProxyTestBase
{
46 public static $mock_upload_max_filesize = 0;
48 public function setUp() {
50 $this->_SERVER
= $_SERVER;
51 self
::$mock_upload_max_filesize = '0';
53 // This is a a hacky workaround to the fact that you cannot use the header()
54 // call in PHPUnit because you hit "headers already sent" errors.
55 $this->sent_headers
= [];
56 $mock_send_header = function($key, $value){
57 $this->sent_headers
[$key] = $value;
59 CloudStorageTools
::setSendHeaderFunction($mock_send_header);
62 public function tearDown() {
63 $_SERVER = $this->_SERVER
;
67 private function expectFilenameTranslation($filename, $blob_key) {
68 $req = new \google\appengine\
CreateEncodedGoogleStorageKeyRequest();
69 $req->setFilename($filename);
71 $resp = new \google\appengine\
CreateEncodedGoogleStorageKeyResponse();
72 $resp->setBlobKey($blob_key);
74 $this->apiProxyMock
->expectCall('blobstore',
75 'CreateEncodedGoogleStorageKey',
80 public function testCreateUploadUrl() {
81 $req = new \google\appengine\files\
GetDefaultGsBucketNameRequest();
82 $resp = new \google\appengine\files\
GetDefaultGsBucketNameResponse();
84 $resp->setDefaultGsBucketName("some_bucket");
86 $this->apiProxyMock
->expectCall("file",
87 "GetDefaultGsBucketName",
91 $req = new \google\appengine\
CreateUploadURLRequest();
92 $req->setSuccessPath('http://foo/bar');
93 $req->setGsBucketName("some_bucket");
95 $resp = new \google\appengine\
CreateUploadURLResponse();
96 $resp->setUrl('http://upload/to/here');
98 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
101 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar');
102 $this->assertEquals($upload_url, 'http://upload/to/here');
103 $this->apiProxyMock
->verify();
106 public function testInvalidSuccessPath() {
107 $this->setExpectedException('\InvalidArgumentException');
108 $upload_url = CloudStorageTools
::createUploadUrl(10);
111 public function testSetMaxBytesPerBlob() {
112 $req = new \google\appengine\
CreateUploadURLRequest();
113 $req->setSuccessPath('http://foo/bar');
114 $req->setMaxUploadSizePerBlobBytes(37337);
115 $req->setGsBucketName("some_bucket");
117 $resp = new \google\appengine\
CreateUploadURLResponse();
118 $resp->setUrl('http://upload/to/here');
120 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
123 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
124 ['max_bytes_per_blob' => 37337,
125 'gs_bucket_name' => 'some_bucket',]);
126 $this->assertEquals($upload_url, 'http://upload/to/here');
127 $this->apiProxyMock
->verify();
130 public function testSetMaxBytesPerBlobIni() {
131 $req = new \google\appengine\
CreateUploadURLRequest();
132 $req->setSuccessPath('http://foo/bar');
133 $req->setMaxUploadSizePerBlobBytes(1 * 1024 * 1024);
134 $req->setGsBucketName("some_bucket");
136 $resp = new \google\appengine\
CreateUploadURLResponse();
137 $resp->setUrl('http://upload/to/here');
139 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
142 self
::$mock_upload_max_filesize = '1M';
143 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
144 ['gs_bucket_name' => 'some_bucket',]);
145 $this->assertEquals($upload_url, 'http://upload/to/here');
146 $this->apiProxyMock
->verify();
149 public function testInvalidMaxBytesPerBlob() {
150 $this->setExpectedException('\InvalidArgumentException');
151 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
152 ['max_bytes_per_blob' => 'not an int',]);
155 public function testNegativeMaxBytesPerBlob() {
156 $this->setExpectedException('\InvalidArgumentException');
157 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
158 ['max_bytes_per_blob' => -1,]);
161 public function testSetMaxBytesTotal() {
162 $req = new \google\appengine\
CreateUploadURLRequest();
163 $req->setSuccessPath('http://foo/bar');
164 $req->setMaxUploadSizeBytes(137337);
165 $req->setMaxUploadSizePerBlobBytes(1 * 1024 * 1024 * 1024);
166 $req->setGsBucketName("some_bucket");
168 $resp = new \google\appengine\
CreateUploadURLResponse();
169 $resp->setUrl('http://upload/to/here');
171 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
174 self
::$mock_upload_max_filesize = '1G';
175 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
176 ['max_bytes_total' => 137337,
177 'gs_bucket_name' => 'some_bucket',]);
178 $this->assertEquals($upload_url, 'http://upload/to/here');
179 $this->apiProxyMock
->verify();
182 public function testInvalidMaxBytes() {
183 $this->setExpectedException('\InvalidArgumentException');
184 $upload_url = CloudStorageTools
::CreateUploadUrl('http://foo/bar',
185 ['max_bytes_total' => 'not an int',]);
188 public function testNegativeMaxBytes() {
189 $this->setExpectedException('\InvalidArgumentException');
190 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
191 ['max_bytes_total' => -1,]);
194 public function testGsBucketName() {
195 $req = new \google\appengine\
CreateUploadURLRequest();
196 $req->setSuccessPath('http://foo/bar');
197 $req->setGsBucketName('my_cool_bucket');
199 $resp = new \google\appengine\
CreateUploadURLResponse();
200 $resp->setUrl('http://upload/to/here');
202 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
205 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
206 ['gs_bucket_name' => 'my_cool_bucket',]);
207 $this->assertEquals($upload_url, 'http://upload/to/here');
208 $this->apiProxyMock
->verify();
211 public function testInvalidGsBucketName() {
212 $this->setExpectedException('\InvalidArgumentException');
213 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
214 ['gs_bucket_name' => null,]);
217 public function testMultipleOptions() {
218 $req = new \google\appengine\
CreateUploadURLRequest();
219 $req->setSuccessPath('http://foo/bar');
220 $req->setMaxUploadSizePerBlobBytes(37337);
221 $req->setMaxUploadSizeBytes(137337);
222 $req->setGsBucketName('my_cool_bucket');
224 $resp = new \google\appengine\
CreateUploadURLResponse();
225 $resp->setUrl('http://upload/to/here');
227 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
230 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
231 ['gs_bucket_name' => 'my_cool_bucket',
232 'max_bytes_total' => 137337,
233 'max_bytes_per_blob' => 37337]);
234 $this->assertEquals($upload_url, 'http://upload/to/here');
235 $this->apiProxyMock
->verify();
238 public function testUrlTooLongException() {
239 $req = new \google\appengine\
CreateUploadURLRequest();
240 $req->setSuccessPath('http://foo/bar');
241 $req->setGsBucketName("some_bucket");
243 $exception = new \google\appengine\runtime\
ApplicationError(
244 BlobstoreServiceError\ErrorCode
::URL_TOO_LONG
, 'message');
246 $this->setExpectedException('\InvalidArgumentException', '');
248 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
251 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
252 ['gs_bucket_name' => 'some_bucket',]);
253 $this->apiProxyMock
->verify();
256 public function testPermissionDeniedException() {
257 $req = new \google\appengine\
CreateUploadURLRequest();
258 $req->setSuccessPath('http://foo/bar');
259 $req->setGsBucketName("some_bucket");
261 $exception = new \google\appengine\runtime\
ApplicationError(
262 BlobstoreServiceError\ErrorCode
::PERMISSION_DENIED
, 'message');
264 $this->setExpectedException(
265 '\google\appengine\api\cloud_storage\CloudStorageException',
266 'Permission Denied');
268 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
271 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
272 ['gs_bucket_name' => 'some_bucket',]);
273 $this->apiProxyMock
->verify();
276 public function testInternalErrorException() {
277 $req = new \google\appengine\
CreateUploadURLRequest();
278 $req->setSuccessPath('http://foo/bar');
279 $req->setGsBucketName("some_bucket");
281 $exception = new \google\appengine\runtime\
ApplicationError(
282 BlobstoreServiceError\ErrorCode
::INTERNAL_ERROR
, 'message');
284 $this->setExpectedException(
285 '\google\appengine\api\cloud_storage\CloudStorageException', '');
287 $this->apiProxyMock
->expectCall('blobstore', 'CreateUploadURL', $req,
290 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
291 ['gs_bucket_name' => 'some_bucket',]);
292 $this->apiProxyMock
->verify();
295 public function testNoDefaultBucketException() {
296 $req = new \google\appengine\files\
GetDefaultGsBucketNameRequest();
297 $resp = new \google\appengine\files\
GetDefaultGsBucketNameResponse();
299 $this->apiProxyMock
->expectCall("file",
300 "GetDefaultGsBucketName",
303 $this->setExpectedException('\InvalidArgumentException');
304 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar');
305 $this->apiProxyMock
->verify();
308 public function testInvalidOptions() {
309 $this->setExpectedException('\InvalidArgumentException');
310 $upload_url = CloudStorageTools
::createUploadUrl('http://foo/bar',
311 ['gs_bucket_name' => 'bucket',
315 public function testServeInvalidGsPrefix() {
316 $this->setExpectedException('\InvalidArgumentException');
317 CloudStorageTools
::serve("/goo/bar.png");
320 public function testServeInvalidBucketObjectName() {
321 $this->setExpectedException(
322 '\InvalidArgumentException',
323 'filename not in the format gs://bucket_name/object_name.');
324 CloudStorageTools
::serve("gs://some_bucket");
327 public function testServeInvalidOptionArray() {
328 $this->setExpectedException('\InvalidArgumentException');
329 CloudStorageTools
::serve("gs://foo/bar.png", ["foo" => true]);
332 public function testServeEndBadRanges() {
333 $ranges = [[null, 1], [null, -1], [2, 1], [-1, 1]];
334 foreach($ranges as $range) {
336 CloudStorageTools
::serve("gs://foo/bar.png",
337 ["start" => $range[0], "end" => $range[1]]);
338 } catch (\InvalidArgumentException
$e) {
341 $this->fail("InvalidArgumentException was not thrown");
345 public function testServeRangeIndexDoNotMatchRangeHeader() {
346 $this->setExpectedException("\InvalidArgumentException");
347 $_SERVER["HTTP_RANGE"] = "bytes=1-2";
348 CloudStorageTools
::serve("gs://foo/bar.png", ["start" => 1, "end" => 3,
349 "use_range" => true]);
352 public function testServeSuccess() {
353 $this->expectFilenameTranslation("/gs/some_bucket/some_object",
355 $filename = "gs://some_bucket/some_object";
356 $expected_headers = [
357 "X-AppEngine-BlobKey" => "some_blob_key",
358 "X-AppEngine-BlobRange" => "bytes=1-2",
359 "Content-Disposition" => "attachment; filename=foo.jpg",
364 "save_as" => "foo.jpg",
366 CloudStorageTools
::serve($filename, $options);
367 $this->assertEquals(ksort($this->sent_headers
), ksort($expected_headers));
368 $this->apiProxyMock
->verify();
371 public function testServeSuccessNegativeRange() {
372 $this->expectFilenameTranslation("/gs/some_bucket/some_object",
374 $filename = "gs://some_bucket/some_object";
375 $expected_headers = [
376 "X-AppEngine-BlobKey" => "some_blob_key",
377 "X-AppEngine-BlobRange" => "bytes=-1001",
378 "Content-Disposition" => "attachment; filename=foo.jpg",
382 "save_as" => "foo.jpg",
384 CloudStorageTools
::serve($filename, $options);
385 $this->assertEquals(ksort($this->sent_headers
), ksort($expected_headers));
386 $this->apiProxyMock
->verify();
389 public function testServeRangeHeaderSuccess() {
390 $this->expectFilenameTranslation("/gs/some_bucket/some_object",
392 $filename = "gs://some_bucket/some_object";
393 $expected_headers = [
394 "X-AppEngine-BlobKey" => "some_blob_key",
395 "X-AppEngine-BlobRange" => "bytes=100-200",
396 "Content-Disposition" => "attachment; filename=foo.jpg",
397 "Content-Type" => "image/jpeg",
400 "save_as" => "foo.jpg",
402 "content_type" => "image/jpeg",
404 $_SERVER["HTTP_RANGE"] = "bytes=100-200";
405 CloudStorageTools
::serve($filename, $options);
406 $this->assertEquals(ksort($this->sent_headers
), ksort($expected_headers));
407 $this->apiProxyMock
->verify();
410 public function testGetDefaultBucketNameSuccess() {
411 $req = new \google\appengine\files\
GetDefaultGsBucketNameRequest();
412 $resp = new \google\appengine\files\
GetDefaultGsBucketNameResponse();
414 $resp->setDefaultGsBucketName("some_bucket");
416 $this->apiProxyMock
->expectCall("file",
417 "GetDefaultGsBucketName",
421 $bucket = CloudStorageTools
::getDefaultGoogleStorageBucketName();
422 $this->assertEquals($bucket, "some_bucket");
423 $this->apiProxyMock
->verify();
426 public function testGetDefaultBucketNameNotSet() {
427 $req = new \google\appengine\files\
GetDefaultGsBucketNameRequest();
428 $resp = new \google\appengine\files\
GetDefaultGsBucketNameResponse();
430 $this->apiProxyMock
->expectCall("file",
431 "GetDefaultGsBucketName",
435 $bucket = CloudStorageTools
::getDefaultGoogleStorageBucketName();
436 $this->assertEquals($bucket, "");
437 $this->apiProxyMock
->verify();
440 // getImageServingUrl tests.
442 public function testGetImageUrlInvalidFilenameType() {
443 $this->setExpectedException('\InvalidArgumentException');
444 $url = CloudStorageTools
::getImageServingUrl(123);
447 public function testGetImageUrlInvalidFilename() {
448 $this->setExpectedException('\InvalidArgumentException');
449 $url = CloudStorageTools
::getImageServingUrl('not-gs://abucket/photo');
452 public function testGetImageUrlCropInvalidType() {
453 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
454 $this->setExpectedException('\InvalidArgumentException');
455 $url = CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg',
457 $this->apiProxyMock
->verify();
460 public function testGetImageUrlCropRequiresSize() {
461 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
462 $this->setExpectedException('\InvalidArgumentException');
463 $url = CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg',
465 $this->apiProxyMock
->verify();
468 public function testGetImageUrlSizeInvalidType() {
469 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
470 $this->setExpectedException(
471 '\InvalidArgumentException',
472 '$options[\'size\'] must be an integer. Actual type: string');
473 $url = CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg',
475 $this->apiProxyMock
->verify();
478 public function testGetImageUrlSizeTooSmall() {
479 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
480 $this->setExpectedException(
481 '\InvalidArgumentException',
482 '$options[\'size\'] must be >= 0 and <= 1600. Actual value: -1');
483 $url = CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg',
485 $this->apiProxyMock
->verify();
488 public function testGetImageUrlSizeTooBig() {
489 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
490 $this->setExpectedException(
491 '\InvalidArgumentException',
492 '$options[\'size\'] must be >= 0 and <= 1600. Actual value: 1601');
493 $url = CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg',
495 $this->apiProxyMock
->verify();
498 public function testGetImageUrlSecureUrlWrongType() {
499 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
500 $this->setExpectedException(
501 '\InvalidArgumentException',
502 '$options[\'secure_url\'] must be a boolean. Actual type: integer');
503 $url = CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg',
504 ['secure_url' => 5]);
505 $this->apiProxyMock
->verify();
508 # getImageServingUrl success case.
509 public function testGetImageUrlSimpleSuccess() {
510 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
511 $req = new \google\appengine\
ImagesGetUrlBaseRequest();
512 $resp = new \google\appengine\
ImagesGetUrlBaseResponse();
513 $req->setBlobKey('some_blob_key');
514 $req->setCreateSecureUrl(false);
515 $resp->setUrl('http://magic-url');
516 $this->apiProxyMock
->expectCall('images',
521 $url = CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg');
522 $this->assertEquals('http://magic-url', $url);
523 $this->apiProxyMock
->verify();
526 public function testGetImageUrlWithSizeAndCropSuccess() {
527 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
528 $req = new \google\appengine\
ImagesGetUrlBaseRequest();
529 $resp = new \google\appengine\
ImagesGetUrlBaseResponse();
530 $req->setBlobKey('some_blob_key');
531 $req->setCreateSecureUrl(false);
532 $resp->setUrl('http://magic-url');
533 $this->apiProxyMock
->expectCall('images',
538 $url = CloudStorageTools
::getImageServingUrl(
539 'gs://mybucket/photo.jpg', ['size' => 40, 'crop' => true]);
540 $this->assertEquals('http://magic-url=s40-c', $url);
541 $this->apiProxyMock
->verify();
544 # getImageServingUrl backend error tests.
545 private function executeGetImageUrlErrorTest($error_code, $expected_message) {
546 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
547 $req = new \google\appengine\
ImagesGetUrlBaseRequest();
548 $resp = new \google\appengine\
ImagesGetUrlBaseResponse();
549 $req->setBlobKey('some_blob_key');
550 $req->setCreateSecureUrl(false);
551 $exception = new \google\appengine\runtime\
ApplicationError(
552 $error_code, 'a message');
554 $this->setExpectedException(
555 '\google\appengine\api\cloud_storage\CloudStorageException',
557 $this->apiProxyMock
->expectCall('images',
561 CloudStorageTools
::getImageServingUrl('gs://mybucket/photo.jpg');
562 $this->apiProxyMock
->verify();
565 public function testGetImageUrlUnspecifiedError() {
566 $this->executeGetImageUrlErrorTest(
567 ImagesServiceError\ErrorCode
::UNSPECIFIED_ERROR
,
568 'Unspecified error with image.');
571 public function testGetImageUrlBadTransform() {
572 $this->executeGetImageUrlErrorTest(
573 ImagesServiceError\ErrorCode
::BAD_TRANSFORM_DATA
,
574 'Bad image transform data.');
577 public function testGetImageUrlNotImage() {
578 $this->executeGetImageUrlErrorTest(
579 ImagesServiceError\ErrorCode
::NOT_IMAGE
,
583 public function testGetImageUrlBadImage() {
584 $this->executeGetImageUrlErrorTest(
585 ImagesServiceError\ErrorCode
::BAD_IMAGE_DATA
,
589 public function testGetImageUrlImageTooLarge() {
590 $this->executeGetImageUrlErrorTest(
591 ImagesServiceError\ErrorCode
::IMAGE_TOO_LARGE
,
595 public function testGetImageUrlInvalidBlobKey() {
596 $this->executeGetImageUrlErrorTest(
597 ImagesServiceError\ErrorCode
::INVALID_BLOB_KEY
,
598 'Invalid blob key for image.');
601 public function testGetImageUrlAccessDenied() {
602 $this->executeGetImageUrlErrorTest(
603 ImagesServiceError\ErrorCode
::ACCESS_DENIED
,
604 'Access denied to image.');
607 public function testGetImageUrlObjectNotFound() {
608 $this->executeGetImageUrlErrorTest(
609 ImagesServiceError\ErrorCode
::OBJECT_NOT_FOUND
,
610 'Image object not found.');
613 public function testGetImageUrlUnknownErrorCode() {
614 $this->executeGetImageUrlErrorTest(999, 'Images Error Code: 999');
617 // deleteImageServingUrl tests.
619 public function testDeleteImageUrlInvalidFilenameType() {
620 $this->setExpectedException('\InvalidArgumentException',
621 'filename must be a string. Actual type: integer');
622 $url = CloudStorageTools
::deleteImageServingUrl(2468);
625 public function testDeleteImageUrlSuccess() {
626 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
627 $req = new \google\appengine\
ImagesDeleteUrlBaseRequest();
628 $resp = new \google\appengine\
ImagesDeleteUrlBaseResponse();
629 $req->setBlobKey('some_blob_key');
630 $this->apiProxyMock
->expectCall('images',
635 CloudStorageTools
::deleteImageServingUrl('gs://mybucket/photo.jpg');
636 $this->apiProxyMock
->verify();
639 public function testDeleteImageUrlAccessDenied() {
640 $this->expectFilenameTranslation('/gs/mybucket/photo.jpg', 'some_blob_key');
641 $req = new \google\appengine\
ImagesDeleteUrlBaseRequest();
642 $resp = new \google\appengine\
ImagesDeleteUrlBaseResponse();
643 $req->setBlobKey('some_blob_key');
644 $exception = new \google\appengine\runtime\
ApplicationError(
645 ImagesServiceError\ErrorCode
::ACCESS_DENIED
, 'a message');
647 $this->setExpectedException(
648 '\google\appengine\api\cloud_storage\CloudStorageException',
649 'Access denied to image.');
650 $this->apiProxyMock
->expectCall('images',
654 CloudStorageTools
::deleteImageServingUrl('gs://mybucket/photo.jpg');
655 $this->apiProxyMock
->verify();
658 public function testGetPublicUrlInProduction() {
661 $gs_filename = sprintf("gs://%s/%s", $bucket, $object);
662 $host = "storage.googleapis.com";
663 putenv("SERVER_SOFTWARE=Google App Engine/1.8.6");
666 $expected = "https://storage.googleapis.com/bucket/object";
667 $actual = CloudStorageTools
::getPublicUrl($gs_filename, true);
668 $this->assertEquals($expected, $actual);
671 $expected = "http://storage.googleapis.com/bucket/object";
672 $actual = CloudStorageTools
::getPublicUrl($gs_filename, false);
673 $this->assertEquals($expected, $actual);
676 public function testGetPublicUrlInDevelopment() {
679 $gs_filename = sprintf("gs://%s/%s", $bucket, $object);
680 $host = "localhost:8080";
681 putenv("SERVER_SOFTWARE=Development/2.0");
682 putenv("HTTP_HOST=" . $host);
685 $expected = "http://localhost:8080/_ah/gcs/bucket/object";
686 $actual = CloudStorageTools
::getPublicUrl($gs_filename, true);
687 $this->assertEquals($expected, $actual);
690 $expected = "http://localhost:8080/_ah/gcs/bucket/object";
691 $actual = CloudStorageTools
::getPublicUrl($gs_filename, false);
692 $this->assertEquals($expected, $actual);
695 public function testGetFilenameFromValidBucketAndObject() {
698 $expected = "gs://bucket/object";
699 $actual = CloudStorageTools
::getFilename($bucket, $object);
700 $this->assertEquals($expected, $actual);
703 public function testGetFilenameFromInvalidBucketNames() {
704 $invalid_bucket_names = [
706 '.another_bad_bucket',
709 str_repeat('a', 224),
711 'foobar' . str_repeat('a', 64)
713 foreach ($invalid_bucket_names as $bucket) {
714 $this->setExpectedException(
715 "\InvalidArgumentException",
716 sprintf("Invalid cloud storage bucket name '%s'", $bucket));
717 CloudStorageTools
::getFilename($bucket, 'foo.txt');
721 public function testGetFilenameFromInvalidObjecNames() {
722 $invalid_object_names = [
723 "WithCarriageReturn\r",
726 foreach ($invalid_object_names as $object) {
727 $this->setExpectedException(
728 "\InvalidArgumentException",
729 sprintf("Invalid cloud storage object name '%s'", $object));
730 CloudStorageTools
::getFilename('foo', $object);