1919var assert = require ( 'assert' ) ;
2020var async = require ( 'async' ) ;
2121var crypto = require ( 'crypto' ) ;
22+ var extend = require ( 'extend' ) ;
2223var fs = require ( 'fs' ) ;
24+ var is = require ( 'is' ) ;
2325var normalizeNewline = require ( 'normalize-newline' ) ;
2426var path = require ( 'path' ) ;
2527var prop = require ( 'propprop' ) ;
@@ -29,6 +31,7 @@ var tmp = require('tmp');
2931var uuid = require ( 'uuid' ) ;
3032
3133var env = require ( '../../../system-test/env.js' ) ;
34+ var util = require ( '@google-cloud/common' ) . util ;
3235
3336var Storage = require ( '../' ) ;
3437var Bucket = Storage . Bucket ;
@@ -76,26 +79,6 @@ describe('storage', function() {
7679 return ;
7780 }
7881
79- function deleteBucket ( bucket , callback ) {
80- // After files are deleted, eventual consistency may require a bit of a
81- // delay to ensure that the bucket recognizes that the files don't exist
82- // anymore.
83- var CONSISTENCY_DELAY_MS = 250 ;
84-
85- bucket . deleteFiles ( {
86- versions : true
87- } , function ( err ) {
88- if ( err ) {
89- callback ( err ) ;
90- return ;
91- }
92-
93- setTimeout ( function ( ) {
94- bucket . delete ( callback ) ;
95- } , CONSISTENCY_DELAY_MS ) ;
96- } ) ;
97- }
98-
9982 async . eachLimit ( buckets , 10 , deleteBucket , done ) ;
10083 } ) ;
10184 } ) ;
@@ -224,7 +207,7 @@ describe('storage', function() {
224207 } ) ;
225208
226209 function createFileWithContent ( content , callback ) {
227- writeToFile ( bucket . file ( generateName ( ) + '.txt' ) , content , callback ) ;
210+ bucket . file ( generateName ( ) + '.txt' ) . save ( content , callback ) ;
228211 }
229212
230213 function isFilePublic ( file , callback ) {
@@ -279,7 +262,7 @@ describe('storage', function() {
279262 } ) ;
280263
281264 function createFileWithContent ( content , callback ) {
282- writeToFile ( bucket . file ( generateName ( ) + '.txt' ) , content , callback ) ;
265+ bucket . file ( generateName ( ) + '.txt' ) . save ( content , callback ) ;
283266 }
284267
285268 function isFilePrivate ( file , callback ) {
@@ -654,8 +637,15 @@ describe('storage', function() {
654637 } ) ;
655638 } ) ;
656639
640+ // These tests will verify that the requesterPays functionality works from
641+ // the perspective of another project.
657642 describe ( 'existing bucket' , function ( ) {
658- var bucket ;
643+ var storageNonWhitelist = new Storage ( {
644+ projectId : env . nonWhitelistProjectId ,
645+ keyFilename : env . nonWhitelistKeyFilename
646+ } ) ;
647+ var bucket ; // the source bucket, which will have requesterPays enabled.
648+ var bucketNonWhitelist ; // the bucket object from the requesting user.
659649
660650 function isRequesterPaysEnabled ( callback ) {
661651 bucket . getMetadata ( function ( err , metadata ) {
@@ -671,6 +661,7 @@ describe('storage', function() {
671661
672662 before ( function ( done ) {
673663 bucket = storage . bucket ( generateName ( ) ) ;
664+ bucketNonWhitelist = storageNonWhitelist . bucket ( bucket . name ) ;
674665 bucket . create ( done ) ;
675666 } ) ;
676667
@@ -711,6 +702,177 @@ describe('storage', function() {
711702 } ) ;
712703 } ) ;
713704 } ) ;
705+
706+ describe ( 'methods that accept userProject' , function ( ) {
707+ var file ;
708+ var USER_PROJECT_OPTIONS = {
709+ userProject : env . nonWhitelistProjectId
710+ } ;
711+
712+ // This acts as a test for the following methods:
713+ //
714+ // - file.save()
715+ // -> file.createWriteStream()
716+ before ( function ( ) {
717+ file = bucketNonWhitelist . file ( generateName ( 'file' ) ) ;
718+
719+ return bucket . enableRequesterPays ( )
720+ . then ( ( ) => bucket . iam . getPolicy ( ) )
721+ . then ( data => {
722+ var policy = data [ 0 ] ;
723+ var clientEmail = require ( env . nonWhitelistKeyFilename )
724+ . client_email ;
725+
726+ policy . bindings . push ( {
727+ role : 'roles/storage.admin' ,
728+ members : [ `serviceAccount:${ clientEmail } ` ]
729+ } ) ;
730+
731+ return bucket . iam . setPolicy ( policy ) ;
732+ } )
733+ . then ( ( ) => file . save ( 'abc' , USER_PROJECT_OPTIONS ) ) ;
734+ } ) ;
735+
736+ // This acts as a test for the following methods:
737+ //
738+ // - bucket.delete({ userProject: ... })
739+ // -> bucket.deleteFiles({ userProject: ... })
740+ // -> bucket.getFiles({ userProject: ... })
741+ // -> file.delete({ userProject: ... })
742+ after ( function ( done ) {
743+ deleteBucket ( bucketNonWhitelist , USER_PROJECT_OPTIONS , done ) ;
744+ } ) ;
745+
746+ function doubleTest ( testFunction ) {
747+ var failureMessage =
748+ 'Bucket is requester pays bucket but no user project provided.' ;
749+
750+ return function ( done ) {
751+ async . series ( [
752+ function ( next ) {
753+ testFunction ( { } , function ( err ) {
754+ assert . strictEqual ( err . message , failureMessage ) ;
755+ next ( ) ;
756+ } ) ;
757+ } ,
758+
759+ function ( next ) {
760+ testFunction ( USER_PROJECT_OPTIONS , next ) ;
761+ }
762+ ] , done ) ;
763+ } ;
764+ }
765+
766+ it ( 'bucket#combine' , function ( done ) {
767+ var files = [
768+ { file : bucketNonWhitelist . file ( 'file-one.txt' ) , contents : '123' } ,
769+ { file : bucketNonWhitelist . file ( 'file-two.txt' ) , contents : '456' }
770+ ] ;
771+
772+ async . each ( files , createFile , function ( err ) {
773+ assert . ifError ( err ) ;
774+
775+ var sourceFiles = files . map ( prop ( 'file' ) ) ;
776+ var destinationFile = bucketNonWhitelist . file ( 'file-one-n-two.txt' ) ;
777+
778+ bucketNonWhitelist . combine (
779+ sourceFiles ,
780+ destinationFile ,
781+ USER_PROJECT_OPTIONS ,
782+ done
783+ ) ;
784+ } ) ;
785+
786+ function createFile ( fileObject , callback ) {
787+ fileObject . file . save (
788+ fileObject . contents ,
789+ USER_PROJECT_OPTIONS ,
790+ callback
791+ ) ;
792+ }
793+ } ) ;
794+
795+ it ( 'bucket#exists' , doubleTest ( function ( options , done ) {
796+ bucketNonWhitelist . exists ( options , done ) ;
797+ } ) ) ;
798+
799+ it ( 'bucket#get' , doubleTest ( function ( options , done ) {
800+ bucketNonWhitelist . get ( options , done ) ;
801+ } ) ) ;
802+
803+ it ( 'bucket#getMetadata' , doubleTest ( function ( options , done ) {
804+ bucketNonWhitelist . get ( options , done ) ;
805+ } ) ) ;
806+
807+ it ( 'bucket#makePrivate' , doubleTest ( function ( options , done ) {
808+ bucketNonWhitelist . makePrivate ( options , done ) ;
809+ } ) ) ;
810+
811+ it ( 'bucket#setMetadata' , doubleTest ( function ( options , done ) {
812+ bucketNonWhitelist . setMetadata ( { newMetadata : true } , options , done ) ;
813+ } ) ) ;
814+
815+ it ( 'bucket#upload' , doubleTest ( function ( options , done ) {
816+ bucketNonWhitelist . upload ( FILES . big . path , options , done ) ;
817+ } ) ) ;
818+
819+ it ( 'file#copy' , doubleTest ( function ( options , done ) {
820+ file . copy ( 'new-file.txt' , options , done ) ;
821+ } ) ) ;
822+
823+ it . skip ( 'file#createReadStream' , doubleTest ( function ( options , done ) {
824+ file . createReadStream ( options )
825+ . on ( 'error' , done )
826+ . on ( 'end' , done )
827+ . on ( 'data' , util . noop ) ;
828+ } ) ) ;
829+
830+ it ( 'file#createResumableUpload' , doubleTest ( function ( opts , done ) {
831+ file . createResumableUpload ( opts , done ) ;
832+ } ) ) ;
833+
834+ it . skip ( 'file#download' , doubleTest ( function ( options , done ) {
835+ file . download ( options , done ) ;
836+ } ) ) ;
837+
838+ it ( 'file#exists' , doubleTest ( function ( options , done ) {
839+ file . exists ( options , done ) ;
840+ } ) ) ;
841+
842+ it ( 'file#get' , doubleTest ( function ( options , done ) {
843+ file . get ( options , done ) ;
844+ } ) ) ;
845+
846+ it ( 'file#getMetadata' , doubleTest ( function ( options , done ) {
847+ file . getMetadata ( options , done ) ;
848+ } ) ) ;
849+
850+ it ( 'file#makePrivate' , doubleTest ( function ( options , done ) {
851+ file . makePrivate ( options , done ) ;
852+ } ) ) ;
853+
854+ it ( 'file#move' , doubleTest ( function ( options , done ) {
855+ var newFile = bucketNonWhitelist . file ( generateName ( 'file' ) ) ;
856+
857+ file . move ( newFile , options , function ( err ) {
858+ if ( err ) {
859+ done ( err ) ;
860+ return ;
861+ }
862+
863+ // Re-create the file. The tests need it.
864+ file . save ( 'newcontent' , done ) ;
865+ } ) ;
866+ } ) ) ;
867+
868+ it ( 'file#setMetadata' , doubleTest ( function ( options , done ) {
869+ file . setMetadata ( { newMetadata : true } , options , done ) ;
870+ } ) ) ;
871+
872+ it ( 'file#setStorageClass' , doubleTest ( function ( options , done ) {
873+ file . setStorageClass ( 'multi-regional' , options , done ) ;
874+ } ) ) ;
875+ } ) ;
714876 } ) ;
715877 } ) ;
716878
@@ -1185,7 +1347,7 @@ describe('storage', function() {
11851347 } ) ;
11861348
11871349 function createFile ( fileObject , callback ) {
1188- writeToFile ( fileObject . file , fileObject . contents , callback ) ;
1350+ fileObject . file . save ( fileObject . contents , callback ) ;
11891351 }
11901352 } ) ;
11911353 } ) ;
@@ -1289,15 +1451,15 @@ describe('storage', function() {
12891451 it ( 'should overwrite file, then get older version' , function ( done ) {
12901452 var versionedFile = bucketWithVersioning . file ( generateName ( ) ) ;
12911453
1292- writeToFile ( versionedFile , 'a' , function ( err ) {
1454+ versionedFile . save ( 'a' , function ( err ) {
12931455 assert . ifError ( err ) ;
12941456
12951457 versionedFile . getMetadata ( function ( err , metadata ) {
12961458 assert . ifError ( err ) ;
12971459
12981460 var initialGeneration = metadata . generation ;
12991461
1300- writeToFile ( versionedFile , 'b' , function ( err ) {
1462+ versionedFile . save ( 'b' , function ( err ) {
13011463 assert . ifError ( err ) ;
13021464
13031465 var firstGenFile = bucketWithVersioning . file ( versionedFile . name , {
@@ -1340,7 +1502,7 @@ describe('storage', function() {
13401502 } ) ;
13411503
13421504 function createFile ( fileObject , callback ) {
1343- writeToFile ( fileObject . file , fileObject . contents , callback ) ;
1505+ fileObject . file . save ( fileObject . contents , callback ) ;
13441506 }
13451507 } ) ;
13461508 } ) ;
@@ -1447,18 +1609,38 @@ describe('storage', function() {
14471609 } ) ;
14481610 } ) ;
14491611
1612+ function deleteBucket ( bucket , options , callback ) {
1613+ if ( is . fn ( options ) ) {
1614+ callback = options ;
1615+ options = { } ;
1616+ }
1617+
1618+ // After files are deleted, eventual consistency may require a bit of a
1619+ // delay to ensure that the bucket recognizes that the files don't exist
1620+ // anymore.
1621+ var CONSISTENCY_DELAY_MS = 250 ;
1622+
1623+ options = extend ( { } , options , {
1624+ versions : true
1625+ } ) ;
1626+
1627+ bucket . deleteFiles ( options , function ( err ) {
1628+ if ( err ) {
1629+ callback ( err ) ;
1630+ return ;
1631+ }
1632+
1633+ setTimeout ( function ( ) {
1634+ bucket . delete ( options , callback ) ;
1635+ } , CONSISTENCY_DELAY_MS ) ;
1636+ } ) ;
1637+ }
1638+
14501639 function deleteFile ( file , callback ) {
14511640 file . delete ( callback ) ;
14521641 }
14531642
14541643 function generateName ( ) {
14551644 return TESTS_PREFIX + uuid . v1 ( ) ;
14561645 }
1457-
1458- function writeToFile ( file , contents , callback ) {
1459- var writeStream = file . createWriteStream ( ) ;
1460- writeStream . once ( 'error' , callback ) ;
1461- writeStream . once ( 'finish' , callback . bind ( null , null ) ) ;
1462- writeStream . end ( contents ) ;
1463- }
14641646} ) ;
0 commit comments