From b39877321ae9124b8c15fb9fa7ddb9c4e0fadecb Mon Sep 17 00:00:00 2001 From: Stephen Sawchuk Date: Mon, 23 Mar 2015 13:31:10 -0400 Subject: [PATCH] update tests + docs --- lib/storage/bucket.js | 133 ++++++++++++++++----------- test/storage/bucket.js | 199 ++++++++++++++++++++++------------------- 2 files changed, 187 insertions(+), 145 deletions(-) diff --git a/lib/storage/bucket.js b/lib/storage/bucket.js index 877f62a856cb..8531d32bb73d 100644 --- a/lib/storage/bucket.js +++ b/lib/storage/bucket.js @@ -411,11 +411,11 @@ Bucket.prototype.getMetadata = function(callback) { }; /** - * Make the bucket publicly readable. + * Make the bucket listing private. * - * You may also choose to make the contents of the bucket publicly readable by - * specifying `includeFiles: true`. This will automatically run - * {module:storage/file#makePublic} for every file in the bucket. + * You may also choose to make the contents of the bucket private by specifying + * `includeFiles: true`. This will automatically run + * {module:storage/file#makePrivate} for every file in the bucket. * * When specifying `includeFiles: true`, use `force: true` to delay execution of * your callback until all files have been processed. By default, the callback @@ -427,51 +427,51 @@ Bucket.prototype.getMetadata = function(callback) { * requests. Use with caution. * * @param {object=} options - The configuration object. - * @param {boolean} options.includeFiles - Make each file in the bucket publicly - * readable. Default: `false`. + * @param {boolean} options.includeFiles - Make each file in the bucket private. + * Default: `false`. * @param {boolean} options.force - Queue errors occurred while making files - * public until all files have been processed. + * private until all files have been processed. * @param {function} callback - The callback function. * * @example * //- - * // Make the bucket publicly readable. + * // Make the bucket private. * //- - * bucket.makePublic(function(err) {}); + * bucket.makePrivate(function(err) {}); * * //- - * // Make the bucket and its contents publicly readable. + * // Make the bucket and its contents private. * //- * var opts = { * includeFiles: true * }; * - * bucket.makePublic(opts, function(err, files) { + * bucket.makePrivate(opts, function(err, files) { * // `err`: * // The first error to occur, otherwise null. * // * // `files`: - * // Array of files successfully made public in the bucket. + * // Array of files successfully made private in the bucket. * }); * * //- - * // Make the bucket and its contents publicly readable, using force to - * // suppress errors until all files have been processed. + * // Make the bucket and its contents private, using force to suppress errors + * // until all files have been processed. * //- * var opts = { * includeFiles: true, * force: true * }; * - * bucket.makePublic(opts, function(errors, files) { + * bucket.makePrivate(opts, function(errors, files) { * // `errors`: * // Array of errors if any occurred, otherwise null. * // * // `files`: - * // Array of files successfully made public in the bucket. + * // Array of files successfully made private in the bucket. * }); */ -Bucket.prototype.makePublic = function(options, callback) { +Bucket.prototype.makePrivate = function(options, callback) { var self = this; if (util.is(options, 'function')) { @@ -480,27 +480,15 @@ Bucket.prototype.makePublic = function(options, callback) { } options = options || {}; - options.public = true; + options.private = true; - async.parallel([ - setPredefinedAcl, - addAclPermissions, - makeFilesPublic - ], callback); + async.parallel([setPredefinedAcl, makeFilesPrivate], callback); function setPredefinedAcl(done) { self.setPredefinedAcl_(options, done); } - function addAclPermissions(done) { - // Allow reading bucket contents while preserving original permissions. - self.acl.default.add({ - entity: 'allUsers', - role: 'READER' - }, done); - } - - function makeFilesPublic(done) { + function makeFilesPrivate(done) { if (!options.includeFiles) { done(); return; @@ -511,11 +499,11 @@ Bucket.prototype.makePublic = function(options, callback) { }; /** - * Make the bucket listing private. + * Make the bucket publicly readable. * - * You may also choose to make the contents of the bucket private by specifying - * `includeFiles: true`. This will automatically run - * {module:storage/file#makePrivate} for every file in the bucket. + * You may also choose to make the contents of the bucket publicly readable by + * specifying `includeFiles: true`. This will automatically run + * {module:storage/file#makePublic} for every file in the bucket. * * When specifying `includeFiles: true`, use `force: true` to delay execution of * your callback until all files have been processed. By default, the callback @@ -527,51 +515,51 @@ Bucket.prototype.makePublic = function(options, callback) { * requests. Use with caution. * * @param {object=} options - The configuration object. - * @param {boolean} options.includeFiles - Make each file in the bucket private. - * Default: `false`. + * @param {boolean} options.includeFiles - Make each file in the bucket publicly + * readable. Default: `false`. * @param {boolean} options.force - Queue errors occurred while making files - * private until all files have been processed. + * public until all files have been processed. * @param {function} callback - The callback function. * * @example * //- - * // Make the bucket private. + * // Make the bucket publicly readable. * //- - * bucket.makePrivate(function(err) {}); + * bucket.makePublic(function(err) {}); * * //- - * // Make the bucket and its contents private. + * // Make the bucket and its contents publicly readable. * //- * var opts = { * includeFiles: true * }; * - * bucket.makePrivate(opts, function(err, files) { + * bucket.makePublic(opts, function(err, files) { * // `err`: * // The first error to occur, otherwise null. * // * // `files`: - * // Array of files successfully made private in the bucket. + * // Array of files successfully made public in the bucket. * }); * * //- - * // Make the bucket and its contents private, using force to suppress errors - * // until all files have been processed. + * // Make the bucket and its contents publicly readable, using force to + * // suppress errors until all files have been processed. * //- * var opts = { * includeFiles: true, * force: true * }; * - * bucket.makePrivate(opts, function(errors, files) { + * bucket.makePublic(opts, function(errors, files) { * // `errors`: * // Array of errors if any occurred, otherwise null. * // * // `files`: - * // Array of files successfully made private in the bucket. + * // Array of files successfully made public in the bucket. * }); */ -Bucket.prototype.makePrivate = function(options, callback) { +Bucket.prototype.makePublic = function(options, callback) { var self = this; if (util.is(options, 'function')) { @@ -580,15 +568,27 @@ Bucket.prototype.makePrivate = function(options, callback) { } options = options || {}; - options.private = true; + options.public = true; - async.parallel([setPredefinedAcl, makeFilesPrivate], callback); + async.parallel([ + setPredefinedAcl, + addAclPermissions, + makeFilesPublic + ], callback); function setPredefinedAcl(done) { self.setPredefinedAcl_(options, done); } - function makeFilesPrivate(done) { + function addAclPermissions(done) { + // Allow reading bucket contents while preserving original permissions. + self.acl.default.add({ + entity: 'allUsers', + role: 'READER' + }, done); + } + + function makeFilesPublic(done) { if (!options.includeFiles) { done(); return; @@ -765,6 +765,23 @@ Bucket.prototype.upload = function(localPath, options, callback) { } }; +/** + * Iterate over all of a bucket's files, calling `file.makePublic()` (public) + * or `file.makePrivate()` (private) on each. + * + * Operations are performed in parallel, up to 10 at once. The first error + * breaks the loop, and will execute the provided callback with it. Specify + * `{ force: true }` to suppress the errors. + * + * @private + * + * @param {object} options - Configuration object. + * @param {boolean} options.force - Supress errors until all files have been + * processed. + * @param {boolean} options.private - Make files private. + * @param {boolean} options.public - Make files public. + * @param {function} callback - The callback function. + */ Bucket.prototype.makeAllFilesPublicPrivate_ = function(options, callback) { var self = this; @@ -831,6 +848,18 @@ Bucket.prototype.makeAllFilesPublicPrivate_ = function(options, callback) { } }; +/** + * Set the predefinedAcl for this bucket to `publicRead` (public) or + * `projectPrivate` (private). + * + * This will also update the metadata on the object with the APIresponse. + * + * @private + * + * @param {object} options - Configuration object. + * @param {boolean} options.private - Set the predefinedAcl to projectPrivate. + * @param {boolean} options.public - Set the predefinedAcl to publicRead. + */ Bucket.prototype.setPredefinedAcl_ = function(options, callback) { var self = this; diff --git a/test/storage/bucket.js b/test/storage/bucket.js index dcb853e0b8dc..a37145c67bc8 100644 --- a/test/storage/bucket.js +++ b/test/storage/bucket.js @@ -446,28 +446,51 @@ describe('Bucket', function() { }; }); - it('should add correct entity and role to the ACL', function(done) { - bucket.acl.add = function(opts) { + it('should set predefined & default ACL, publicize files', function(done) { + bucket.setPredefinedAcl = function(opts, callback) { + assert.strictEqual(options.public, true); + assert.strictEqual(options.force, true); + callback(); + }; + + bucket.acl.default.add = function(opts, callback) { assert.equal(opts.entity, 'allUsers'); assert.equal(opts.role, 'READER'); - done(); + callback(); + }; + + bucket.makeAllFilesPublicPrivate_ = function(opts, callback) { + assert.strictEqual(opts.public, true); + assert.strictEqual(opts.force, true); + callback(); }; - bucket.makePublic(assert.ifError); + bucket.makePublic({ + includeFiles: true, + force: true + }, done); }); - it('should execute callback', function(done) { - bucket.acl.add = function(opts, callback) { + it('should not make files public by default', function(done) { + bucket.setPredefinedAcl = function(opts, callback) { + callback(); + }; + + bucket.acl.default.add = function(opts, callback) { callback(); }; + bucket.makeAllFilesPublicPrivate_ = function() { + throw new Error('Please, no. I do not want to be called.'); + }; + bucket.makePublic(done); }); it('should execute callback with error', function(done) { var error = new Error('Error.'); - bucket.acl.add = function(opts, callback) { + bucket.setPredefinedAcl_ = function(opts, callback) { callback(error); }; @@ -476,81 +499,41 @@ describe('Bucket', function() { done(); }); }); - - describe('file ACL updates', function() { - it('should update ACL for files in the bucket', function(done) { - bucket.acl.add = function (opts, callback) { - callback(); - }; - - bucket.makeAllFilesPublicPrivate_ = function() { - done(); - }; - - bucket.makePublic({ includeFiles: true }, assert.ifError); - }); - - it('should pass correct options', function(done) { - bucket.acl.add = function (opts, callback) { - callback(); - }; - - bucket.makeAllFilesPublicPrivate_ = function(opts) { - assert.strictEqual(opts.public, true); - assert.strictEqual(opts.force, true); - - done(); - }; - - bucket.makePublic({ includeFiles: true, force: true }, assert.ifError); - }); - }); }); describe('makePrivate', function() { - it('update the predefinedAcl metadata property', function(done) { - bucket.makeReq_ = function(method, path, query, body) { - assert.equal(method, 'PATCH'); - assert.equal(path, ''); - assert.deepEqual(query, { - predefinedAcl: 'projectPrivate', - predefinedDefaultObjectAcl: 'projectPrivate' - }); - assert.deepEqual(body, { acl: null }); - done(); + it('should set predefinedAcl & privatize files', function(done) { + bucket.setPredefinedAcl_ = function(opts, callback) { + assert.strictEqual(opts.private, true); + assert.strictEqual(opts.force, true); + callback(); }; - bucket.makePrivate(); - }); - - it('should update metadata from response', function(done) { - var fakeMetadata = { a: 'b', c: 'd' }; - - bucket.makeReq_ = function(method, path, query, body, callback) { - callback(null, fakeMetadata); + bucket.makeAllFilesPublicPrivate_ = function(opts, callback) { + assert.strictEqual(opts.private, true); + assert.strictEqual(opts.force, true); + callback(); }; - bucket.makePrivate(function(err) { - assert.ifError(err); - - assert.deepEqual(bucket.metadata, fakeMetadata); - - done(); - }); + bucket.makePrivate({ includeFiles: true, force: true }, done); }); - it('should execute callback', function(done) { - bucket.makeReq_ = function(method, path, query, body, callback) { + it('should not make files private by default', function(done) { + bucket.setPredefinedAcl_ = function(opts, callback) { callback(); }; + bucket.makeAllFilesPublicPrivate_ = function() { + throw new Error('Please, no. I do not want to be called.'); + }; + bucket.makePrivate(done); }); it('should execute callback with error', function(done) { var error = new Error('Error.'); - bucket.makeReq_ = function(method, path, query, body, callback) { + bucket.setPredefinedAcl_ = function(opts, callback) { callback(error); }; @@ -559,35 +542,6 @@ describe('Bucket', function() { done(); }); }); - - describe('file ACL updates', function() { - it('should update ACL for files in the bucket', function(done) { - bucket.makeReq_ = function(method, path, query, body, callback) { - callback(); - }; - - bucket.makeAllFilesPublicPrivate_ = function() { - done(); - }; - - bucket.makePrivate({ includeFiles: true }, assert.ifError); - }); - - it('should pass correct options', function(done) { - bucket.makeReq_ = function(method, path, query, body, callback) { - callback(); - }; - - bucket.makeAllFilesPublicPrivate_ = function(opts) { - assert.strictEqual(opts.private, true); - assert.strictEqual(opts.force, true); - - done(); - }; - - bucket.makePrivate({ includeFiles: true, force: true }, done); - }); - }); }); describe('setMetadata', function() { @@ -954,6 +908,65 @@ describe('Bucket', function() { }); }); + describe('setPredefinedAcl_', function() { + it('should make correct public PATCH request', function(done) { + bucket.makeReq_ = function(method, path, query, body) { + assert.equal(method, 'PATCH'); + assert.equal(path, ''); + assert.deepEqual(query, { + predefinedAcl: 'publicRead' + }); + assert.deepEqual(body, { acl: null }); + done(); + }; + + bucket.setPredefinedAcl_({ public: true }, assert.ifError); + }); + + it('should make correct private PATCH request', function(done) { + bucket.makeReq_ = function(method, path, query, body) { + assert.equal(method, 'PATCH'); + assert.equal(path, ''); + assert.deepEqual(query, { + predefinedAcl: 'projectPrivate' + }); + assert.deepEqual(body, { acl: null }); + done(); + }; + + bucket.setPredefinedAcl_({ private: true }, assert.ifError); + }); + + it('should update metadata from response', function(done) { + var fakeMetadata = { a: 'b', c: 'd' }; + + bucket.makeReq_ = function(method, path, query, body, callback) { + callback(null, fakeMetadata); + }; + + bucket.setPredefinedAcl_({}, function(err) { + assert.ifError(err); + + assert.deepEqual(bucket.metadata, fakeMetadata); + + done(); + }); + }); + + it('should execute callback with error', function(done) { + var error = new Error('Error.'); + + bucket.makeReq_ = function(method, path, query, body, callback) { + callback(error); + }; + + bucket.setPredefinedAcl_({ public: true }, function(err) { + assert.equal(err, error); + done(); + }); + }); + }); + describe('makeReq_', function() { var method = 'POST'; var path = '/path';