diff --git a/pubsub/topics.js b/pubsub/topics.js index ef9a0c7ec2..b7dfd0687a 100644 --- a/pubsub/topics.js +++ b/pubsub/topics.js @@ -37,7 +37,7 @@ function listTopics (callback) { return; } - console.log(`Topics:`); + console.log('Topics:'); topics.forEach((topic) => console.log(topic.name)); callback(); }); @@ -257,7 +257,7 @@ function testTopicPermissions (topicName, callback) { // The command-line program const cli = require(`yargs`); -const makeHandler = require(`../utils`).makeHandler; +const noop = require(`../utils`).noop; const program = module.exports = { listTopics: listTopics, @@ -277,13 +277,13 @@ const program = module.exports = { cli .demand(1) .command(`list`, `Lists all topics in the current project.`, {}, (options) => { - program.listTopics(makeHandler(false)); + program.listTopics(noop); }) .command(`create `, `Creates a new topic.`, {}, (options) => { - program.createTopic(options.topicName, makeHandler(false)); + program.createTopic(options.topicName, noop); }) - .command(`delete `, `Deletes the a topic.`, {}, (options) => { - program.deleteTopic(options.topicName, makeHandler(false)); + .command(`delete `, `Deletes a topic.`, {}, (options) => { + program.deleteTopic(options.topicName, noop); }) .command(`publish `, `Publishes a message.`, {}, (options) => { try { @@ -291,16 +291,16 @@ cli } catch (err) { // Ignore error } - program.publishMessage(options.topicName, options.message, makeHandler(false)); + program.publishMessage(options.topicName, options.message, noop); }) .command(`get-policy `, `Gets the IAM policy for a topic.`, {}, (options) => { - program.getTopicPolicy(options.topicName, makeHandler(false)); + program.getTopicPolicy(options.topicName, noop); }) .command(`set-policy `, `Sets the IAM policy for a topic.`, {}, (options) => { - program.setTopicPolicy(options.topicName, makeHandler(false)); + program.setTopicPolicy(options.topicName, noop); }) .command(`test-permissions `, `Tests the permissions for a topic.`, {}, (options) => { - program.testTopicPermissions(options.topicName, makeHandler(false)); + program.testTopicPermissions(options.topicName, noop); }) .example(`node $0 list`, `Lists all topics in the current project.`) .example(`node $0 create greetings`, `Creates a new topic named "greetings".`) diff --git a/storage/README.md b/storage/README.md index 3af203b46b..b76f23caec 100644 --- a/storage/README.md +++ b/storage/README.md @@ -37,27 +37,38 @@ __Usage:__ `node acl --help` ``` Commands: - add Add access controls on a bucket or file. - get [entity] Get access controls on a bucket or file. - delete Delete access controls from a bucket or file. + print-bucket-acl Prints the ACL for a bucket. + print-bucket-acl-for-user Prints a user's ACL for a bucket. + add-bucket-owner Adds a user as an owner of a bucket. + remove-bucket-owner Removes a user from the ACL of a bucket. + add-bucket-default-owner Adds a user as an owner in the default ACL of a bucket. + remove-bucket-default-owner Removes a user from the default ACL of a bucket. + print-file-acl Prints the ACL for a file. + print-file-acl-for-user Prints a user's ACL for a file. + add-file-owner Adds a user as an owner of a file. + remove-file-owner Removes a user from the ACL of a file. Options: - --bucket, -b The target storage bucket. [string] [required] - --default, -d Whether to set default access - controls. Only valid when setting - access controls on a bucket. [boolean] - --file, -f The target file. [string] - --help Show help [boolean] + --help Show help [boolean] Examples: - node acl add user-bob@domain.com OWNER -b mybucket Add OWNER access controls for - "user-bob@domain.com" to "mybucket". - node acl add viewers-2256 WRITER -b mybucket -d Add default WRITER access controls to - "mybucket" for "viewers-2256". - node acl get editors-1234 -b mybucket Get access controls for "editors-1234" in - "mybucket". - node acl delete -b mybucket -f file.txt Delete all access controls for all entities - from "file.txt" in "mybucket". + node acl print-bucket-acl my-bucket Prints the ACL for a bucket named "my-bucket". + node acl print-bucket-acl-for-user my-bucket bob@company.com Prints a user's ACL for a bucket named "my-bucket". + node acl add-bucket-owner my-bucket bob@company.com Adds "bob@company.com" as an owner of a bucket named + "my-bucket". + node acl remove-bucket-owner my-bucket bob@company.com Removes "bob@company.com" from the ACL of a bucket named + "my-bucket". + node acl add-bucket-default-owner my-bucket bob@company.com Adds "bob@company.com" as an owner in the default ACL of + a bucket named "my-bucket". + node acl remove-bucket-default-owner my-bucket Removes "bob@company.com" from the default ACL of a + bob@company.com bucket named "my-bucket". + node acl print-file-acl my-bucket file.txt Prints the ACL for a file named "file.txt". + node acl print-file-acl-for-user my-bucket file.txt Prints a user's ACL for a file named "file.txt". + bob@company.com + node acl add-file-owner my-bucket file.txt bob@company.com Adds "bob@company.com" as an owner of a file named + "file.txt". + node acl remove-file-owner my-bucket file.txt Removes "bob@company.com" from the ACL of a file named + bob@company.com "file.txt". For more information, see https://cloud.google.com/storage/docs/access-control/create-manage-lists ``` @@ -73,17 +84,17 @@ __Usage:__ `node buckets --help` ``` Commands: - create Create a new bucket with the given name. - list List all buckets in the authenticated project. - delete Delete the specified bucket. + create Creates a new bucket. + list Lists all buckets in the current project. + delete Deletes a bucket. Options: - --help Show help [boolean] + --help Show help [boolean] Examples: - node buckets create my-bucket Create a new bucket named "my-bucket". - node buckets list List all buckets in the authenticated project. - node buckets delete my-bucket Delete "my-bucket". + node buckets create my-bucket Creates a new bucket named "my-bucket". + node buckets list Lists all buckets in the current project. + node buckets delete my-bucket Deletes a bucket named "my-bucket". For more information, see https://cloud.google.com/storage/docs ``` @@ -99,21 +110,21 @@ __Usage:__ `node encryption --help` ``` Commands: - generate-encryption-key Generate a sample encryption key. - upload Upload an encrypted file to a bucket. - download Download an encrypted file from a bucket. - rotate Rotate encryption keys for a file. + generate-encryption-key Generate a sample encryption key. + upload Encrypts and uploads a file. + download Decrypts and downloads a file. + rotate Rotates encryption keys for a file. Options: - --help Show help [boolean] + --help Show help [boolean] Examples: node encryption generate-encryption-key Generate a sample encryption key. - node encryption upload my-bucket resources/test.txt Upload "resources/test.txt" to + node encryption upload my-bucket ./resources/test.txt Encrypts and uploads "resources/test.txt" to file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= "gs://my-bucket/file_encrypted.txt". - node encryption download my-bucket file_encrypted.txt Download "gs://my-bucket/file_encrypted.txt" to - ./file.txt QxhqaZEqBGVTW55HhQw9Q= "./file.txt". - node encryption rotate my-bucket file_encrypted.txt Rotate encryptiong keys for + node encryption download my-bucket file_encrypted.txt Decrypts and downloads + ./file.txt QxhqaZEqBGVTW55HhQw9Q= "gs://my-bucket/file_encrypted.txt" to "./file.txt". + node encryption rotate my-bucket file_encrypted.txt Rotates encryptiong keys for QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q= "gs://my-bucket/file_encrypted.txt". For more information, see https://cloud.google.com/storage/docs @@ -130,33 +141,34 @@ __Usage:__ `node files --help` ``` Commands: - list [options] List files in a bucket, optionally filtering - by a prefix. - upload Upload a local file to a bucket. - download Download a file from a bucket. - delete Delete a file from a bucket. - getMetadata Get metadata for a file in a bucket. - makePublic Make a file public in a bucket. - move Rename a file in a bucket. - copy Copy a file in a bucket to another bucket. + list [prefix] [delimiter] Lists files in a bucket, optionally filtering by a + prefix. + upload Uploads a local file to a bucket. + download Downloads a file from a bucket. + delete Deletes a file from a bucket. + get-metadata Gets the metadata for a file. + make-public Makes a file public. + generate-signed-url Generates a signed URL for a file. + move Moves a file to a new location within the same bucket, + i.e. rename the file. + copy Copies a file in a bucket to another bucket. + Options: - --help Show help [boolean] + --help Show help [boolean] Examples: - node files list my-bucket List files in "my-bucket". - node files list my-bucket -p public/ List files in "my-bucket" filtered by prefix - "public/". - node files upload my-bucket ./file.txt Upload "./file.txt" to "my-bucket". - node files download my-bucket file.txt ./file.txt Download "gs://my-bucket/file.txt" to - "./file.txt". - node files delete my-bucket file.txt Delete "gs://my-bucket/file.txt". - node files getMetadata my-bucket file.txt Get metadata for "gs://my-bucket/file.txt". - node files makePublic my-bucket file.txt Make "gs://my-bucket/file.txt" public. - node files move my-bucket file.txt file2.txt Rename "gs://my-bucket/file.txt" to - "gs://my-bucket/file2.txt". - node files copy my-bucket file.txt my-other-bucket Copy "gs://my-bucket/file.txt" to - file.txt "gs://my-other-bucket/file.txt". + node files list my-bucket Lists files in "my-bucket". + node files list my-bucket public/ Lists files in "my-bucket" filtered by prefix "public/". + node files upload my-bucket ./file.txt Uploads "./file.txt" to "my-bucket". + node files download my-bucket file.txt ./file.txt Downloads "gs://my-bucket/file.txt" to "./file.txt". + node files delete my-bucket file.txt Deletes "gs://my-bucket/file.txt". + node files get-metadata my-bucket file.txt Gets the metadata for "gs://my-bucket/file.txt". + node files make-public my-bucket file.txt Makes "gs://my-bucket/file.txt" public. + node files move my-bucket file.txt file2.txt Renames "gs://my-bucket/file.txt" to + "gs://my-bucket/file2.txt". + node files copy my-bucket file.txt my-other-bucket file.txt Copies "gs://my-bucket/file.txt" to + "gs://my-other-bucket/file.txt". For more information, see https://cloud.google.com/storage/docs ``` diff --git a/storage/acl.js b/storage/acl.js index cd09323242..50bf805b54 100644 --- a/storage/acl.js +++ b/storage/acl.js @@ -1,172 +1,296 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This application demonstrates how to perform basic operations on bucket and + * file Access Control Lists with the Google Cloud Storage API. + * + * For more information, see the README.md under /storage and the documentation + * at https://cloud.google.com/storage/docs. + */ 'use strict'; -// [START all] -// [START setup] -// By default, the client will authenticate using the service account file -// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use -// the project specified by the GCLOUD_PROJECT environment variable. See -// https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication -var Storage = require('@google-cloud/storage'); +const Storage = require('@google-cloud/storage'); -// Instantiate a storage client -var storage = Storage(); -// [END setup] +// [START storage_print_bucket_acl] +function printBucketAcl (bucketName, callback) { + // Instantiates a client + const storageClient = Storage(); -// [START add_access_control] -/** - * Add access controls to a bucket or file. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The bucket for the new access controls. - * @param {string} options.entity The entity for the new access controls. - * @param {string} options.role The role for the new access controls. - * @param {string} [options.file] Optional. The file for the new access controls. - * @param {boolean} [options.default] Optional. Whether to set default access controls. - * @param {function} callback The callback function. - */ -function addAccessControl (options, callback) { - // Reference the specified storage bucket - var bucket = storage.bucket(options.bucket); - // Reference the bucket's acl resource - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - var acl = bucket.acl; - - if (options.file) { - // Optionally target a file's acl resource - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - acl = bucket.file(options.file).acl; - } else if (options.default) { - // Optionally add "default" access controls to the bucket - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - acl = acl.default; - } + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - // Specify the entity and role for the new access control object - var config = { - entity: options.entity, - role: options.role + // Gets the ACL for the bucket + bucket.acl.get((err, aclObjects) => { + if (err) { + callback(err); + return; + } + + aclObjects.forEach((aclObject) => { + console.log(`${aclObject.role}: ${aclObject.entity}`); + }); + callback(); + }); +} +// [END storage_print_bucket_acl] + +// [START storage_print_bucket_acl_for_user] +function printBucketAclForUser (bucketName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + const options = { + // Specify the user + entity: `user-${userEmail}` }; - acl.add(config, function (err, aclObject) { + // Gets the user's ACL for the bucket + bucket.acl.get(options, (err, aclObject) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Added access controls to: gs://%s' + (options.file ? '/%s' : ''), options.bucket, options.file || ''); - return callback(null, aclObject); + console.log(`${aclObject.role}: ${aclObject.entity}`); + callback(); }); } -// [END add_access_control] +// [END storage_print_bucket_acl_for_user] -// [START get_access_control] -/** - * Get access controls for a bucket or file. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The bucket to target. - * @param {string} [options.entity] Optional. The entity to filter by. - * @param {string} [options.file] Optional. The file to target. - * @param {boolean} [options.default] Optional. Whether to get default access controls. - * @param {function} callback The callback function. - */ -function getAccessControl (options, callback) { - // Reference the specified storage bucket - var bucket = storage.bucket(options.bucket); - // Reference the bucket's acl resource - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - var acl = bucket.acl; - - if (options.file) { - // Optionally target a file's acl resource - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - acl = bucket.file(options.file).acl; - } else if (options.default) { - // Optionally get "default" access controls for the bucket - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - acl = acl.default; - } +// [START storage_add_bucket_owner] +function addBucketOwner (bucketName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); - if (options.entity) { - // Get a list of access controls for a specific entity - acl.get({ entity: options.entity }, handleResponse); - } else { - // Get a list of all access controls - acl.get(handleResponse); - } + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - function handleResponse (err, aclObject) { + // Makes the user an owner of the bucket. You can use addAllUsers(), + // addDomain(), addProject(), addGroup(), and addAllAuthenticatedUsers() + // to grant access to different types of entities. You can also use "readers" + // and "writers" to grant different roles. + bucket.acl.owners.addUser(userEmail, (err) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Got access controls for: gs://%s' + (options.file ? '/%s' : ''), options.bucket, options.file || ''); - return callback(null, aclObject); - } + console.log(`Added user ${userEmail} as an owner on bucket ${bucketName}.`); + callback(); + }); } -// [END get_access_control] +// [END storage_add_bucket_owner] -// [START delete_access_control] -/** - * Delete access controls from a bucket or file. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The bucket to target. - * @param {string} options.entity The entity whose access is to be revoked. - * @param {string} [options.file] Optional. The file to target. - * @param {boolean} [options.default] Optional. Whether to delete default access controls. - * @param {function} callback The callback function. - */ -function deleteAccessControl (options, callback) { - // Reference the specified storage bucket - var bucket = storage.bucket(options.bucket); - // Reference the bucket's acl resource - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - var acl = bucket.acl; - - if (options.file) { - // Optionally target a file's acl resource - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - acl = bucket.file(options.file).acl; - } else if (options.default) { - // Optionally delete "default" access controls from the bucket - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - acl = acl.default; - } +// [START storage_remove_bucket_owner] +function removeBucketOwner (bucketName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - // Delete access controls for a specific entity - acl.delete({ entity: options.entity }, function (err) { + // Removes the user from the access control list of the bucket. You can use + // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and + // deleteAllAuthenticatedUsers() to remove access for different types of entities. + bucket.acl.owners.deleteUser(userEmail, (err) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Deleted access controls from: gs://%s' + (options.file ? '/%s' : ''), options.bucket, options.file || ''); - return callback(null); + console.log(`Removed user ${userEmail} from bucket ${bucketName}.`); + callback(); }); } -// [END delete_access_control] -// [END all] +// [END storage_remove_bucket_owner] + +// [START storage_add_bucket_default_owner] +function addBucketDefaultOwner (bucketName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // Makes the user an owner in the default ACL of the bucket. You can use + // addAllUsers(), addDomain(), addProject(), addGroup(), and + // addAllAuthenticatedUsers() to grant access to different types of entities. + // You can also use "readers" and "writers" to grant different roles. + bucket.acl.default.owners.addUser(userEmail, (err) => { + if (err) { + callback(err); + return; + } + + console.log(`Added user ${userEmail} as an owner on bucket ${bucketName}.`); + callback(); + }); +} +// [END storage_add_bucket_default_owner] + +// [START storage_remove_bucket_default_owner] +function removeBucketDefaultOwner (bucketName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // Removes the user from the access control list of the bucket. You can use + // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and + // deleteAllAuthenticatedUsers() to remove access for different types of entities. + bucket.acl.default.owners.deleteUser(userEmail, (err) => { + if (err) { + callback(err); + return; + } + + console.log(`Removed user ${userEmail} from bucket ${bucketName}.`); + callback(); + }); +} +// [END storage_remove_bucket_default_owner] + +// [START storage_print_file_acl] +function printFileAcl (bucketName, fileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + // Gets the ACL for the file + file.acl.get((err, aclObjects) => { + if (err) { + callback(err); + return; + } + + aclObjects.forEach((aclObject) => { + console.log(`${aclObject.role}: ${aclObject.entity}`); + }); + callback(); + }); +} +// [END storage_print_file_acl] + +// [START storage_print_file_acl_for_user] +function printFileAclForUser (bucketName, fileName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + const options = { + // Specify the user + entity: `user-${userEmail}` + }; + + // Gets the user's ACL for the file + file.acl.get(options, (err, aclObject) => { + if (err) { + callback(err); + return; + } + + console.log(`${aclObject.role}: ${aclObject.entity}`); + callback(); + }); +} +// [END storage_print_file_acl_for_user] + +// [START storage_add_file_owner] +function addFileOwner (bucketName, fileName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + // Makes the user an owner of the file. You can use addAllUsers(), + // addDomain(), addProject(), addGroup(), and addAllAuthenticatedUsers() + // to grant access to different types of entities. You can also use "readers" + // and "writers" to grant different roles. + file.acl.owners.addUser(userEmail, (err) => { + if (err) { + callback(err); + return; + } + + console.log(`Added user ${userEmail} as an owner on file ${fileName}.`); + callback(); + }); +} +// [END storage_add_file_owner] + +// [START storage_remove_file_owner] +function removeFileOwner (bucketName, fileName, userEmail, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + // Removes the user from the access control list of the file. You can use + // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and + // deleteAllAuthenticatedUsers() to remove access for different types of entities. + file.acl.owners.deleteUser(userEmail, (err) => { + if (err) { + callback(err); + return; + } + + console.log(`Removed user ${userEmail} from file ${fileName}.`); + callback(); + }); +} +// [END storage_remove_file_owner] // The command-line program -var cli = require('yargs'); -var utils = require('../utils'); +const cli = require(`yargs`); +const utils = require(`../utils`); -var program = module.exports = { - addAccessControl: addAccessControl, - getAccessControl: getAccessControl, - deleteAccessControl: deleteAccessControl, +const program = module.exports = { + printBucketAcl: printBucketAcl, + printBucketAclForUser: printBucketAclForUser, + addBucketOwner: addBucketOwner, + removeBucketOwner: removeBucketOwner, + addBucketDefaultOwner: addBucketDefaultOwner, + removeBucketDefaultOwner: removeBucketDefaultOwner, + printFileAcl: printFileAcl, + printFileAclForUser: printFileAclForUser, + addFileOwner: addFileOwner, + removeFileOwner: removeFileOwner, main: function (args) { // Run the command-line program cli.help().strict().parse(args).argv; @@ -175,45 +299,49 @@ var program = module.exports = { cli .demand(1) - .command('add ', 'Add access controls on a bucket or file.', {}, function (options) { - program.addAccessControl(utils.pick(options, ['entity', 'role', 'bucket', 'default', 'file']), utils.makeHandler()); + .command(`print-bucket-acl `, `Prints the ACL for a bucket.`, {}, (opts) => { + program.printBucketAcl(opts.bucketName, utils.noop); }) - .command('get [entity]', 'Get access controls on a bucket or file.', {}, function (options) { - program.getAccessControl(utils.pick(options, ['entity', 'bucket', 'default', 'file']), utils.makeHandler()); + .command(`print-bucket-acl-for-user `, `Prints a user's ACL for a bucket.`, {}, (opts) => { + program.printBucketAclForUser(opts.bucketName, opts.userEmail, utils.noop); }) - .command('delete ', 'Delete access controls from a bucket or file.', {}, function (options) { - program.deleteAccessControl(utils.pick(options, ['entity', 'bucket', 'default', 'file']), utils.makeHandler()); + .command(`add-bucket-owner `, `Adds a user as an owner of a bucket.`, {}, (opts) => { + program.addBucketOwner(opts.bucketName, opts.userEmail, utils.noop); }) - .example('node $0 add user-bob@domain.com OWNER -b mybucket', 'Add OWNER access controls for "user-bob@domain.com" to "mybucket".') - .example('node $0 add viewers-2256 WRITER -b mybucket -d', 'Add default WRITER access controls to "mybucket" for "viewers-2256".') - .example('node $0 get editors-1234 -b mybucket', 'Get access controls for "editors-1234" in "mybucket".') - .example('node $0 delete -b mybucket -f file.txt', 'Delete all access controls for all entities from "file.txt" in "mybucket".') - .options({ - bucket: { - alias: 'b', - global: true, - demand: true, - requiresArg: true, - type: 'string', - description: 'The target storage bucket.' - }, - default: { - alias: 'd', - global: true, - type: 'boolean', - description: 'Whether to set default access controls. Only valid when setting access controls on a bucket.' - }, - file: { - alias: 'f', - global: true, - requiresArg: true, - type: 'string', - description: 'The target file.' - } + .command(`remove-bucket-owner `, `Removes a user from the ACL of a bucket.`, {}, (opts) => { + program.removeBucketOwner(opts.bucketName, opts.userEmail, utils.noop); + }) + .command(`add-bucket-default-owner `, `Adds a user as an owner in the default ACL of a bucket.`, {}, (opts) => { + program.addBucketDefaultOwner(opts.bucketName, opts.userEmail, utils.noop); + }) + .command(`remove-bucket-default-owner `, `Removes a user from the default ACL of a bucket.`, {}, (opts) => { + program.removeBucketDefaultOwner(opts.bucketName, opts.userEmail, utils.noop); + }) + .command(`print-file-acl `, `Prints the ACL for a file.`, {}, (opts) => { + program.printFileAcl(opts.bucketName, opts.fileName, utils.noop); + }) + .command(`print-file-acl-for-user `, `Prints a user's ACL for a file.`, {}, (opts) => { + program.printFileAclForUser(opts.bucketName, opts.fileName, opts.userEmail, utils.noop); + }) + .command(`add-file-owner `, `Adds a user as an owner of a file.`, {}, (opts) => { + program.addFileOwner(opts.bucketName, opts.fileName, opts.userEmail, utils.noop); + }) + .command(`remove-file-owner `, `Removes a user from the ACL of a file.`, {}, (opts) => { + program.removeFileOwner(opts.bucketName, opts.fileName, opts.userEmail, utils.noop); }) - .wrap(100) + .example(`node $0 print-bucket-acl my-bucket`, `Prints the ACL for a bucket named "my-bucket".`) + .example(`node $0 print-bucket-acl-for-user my-bucket bob@company.com`, `Prints a user's ACL for a bucket named "my-bucket".`) + .example(`node $0 add-bucket-owner my-bucket bob@company.com`, `Adds "bob@company.com" as an owner of a bucket named "my-bucket".`) + .example(`node $0 remove-bucket-owner my-bucket bob@company.com`, `Removes "bob@company.com" from the ACL of a bucket named "my-bucket".`) + .example(`node $0 add-bucket-default-owner my-bucket bob@company.com`, `Adds "bob@company.com" as an owner in the default ACL of a bucket named "my-bucket".`) + .example(`node $0 remove-bucket-default-owner my-bucket bob@company.com`, `Removes "bob@company.com" from the default ACL of a bucket named "my-bucket".`) + .example(`node $0 print-file-acl my-bucket file.txt`, `Prints the ACL for a file named "file.txt".`) + .example(`node $0 print-file-acl-for-user my-bucket file.txt bob@company.com`, `Prints a user's ACL for a file named "file.txt".`) + .example(`node $0 add-file-owner my-bucket file.txt bob@company.com`, `Adds "bob@company.com" as an owner of a file named "file.txt".`) + .example(`node $0 remove-file-owner my-bucket file.txt bob@company.com`, `Removes "bob@company.com" from the ACL of a file named "file.txt".`) + .wrap(120) .recommendCommands() - .epilogue('For more information, see https://cloud.google.com/storage/docs/access-control/create-manage-lists'); + .epilogue(`For more information, see https://cloud.google.com/storage/docs/access-control/create-manage-lists`); if (module === require.main) { program.main(process.argv.slice(2)); diff --git a/storage/buckets.js b/storage/buckets.js index 9d002d4346..53a20e03ce 100644 --- a/storage/buckets.js +++ b/storage/buckets.js @@ -1,103 +1,99 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -// [START all] -// [START setup] -// By default, the client will authenticate using the service account file -// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use -// the project specified by the GCLOUD_PROJECT environment variable. See -// https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication -var Storage = require('@google-cloud/storage'); - -// Instantiate a storage client -var storage = Storage(); -// [END setup] - -// [START create_bucket] /** - * Creates a new bucket with the given name. + * This application demonstrates how to perform basic operations on buckets with + * the Google Cloud Storage API. * - * @param {string} name The name of the new bucket. - * @param {function} cb The callback function. + * For more information, see the README.md under /storage and the documentation + * at https://cloud.google.com/storage/docs. */ -function createBucket (name, callback) { - var bucket = storage.bucket(name); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - bucket.create(function (err, bucket) { +'use strict'; + +// [START all] +const Storage = require('@google-cloud/storage'); + +// [START storage_create_bucket] +function createBucket (bucketName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // Creates a new bucket, e.g. "my-new-bucket" + storageClient.createBucket(bucketName, (err, bucket) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Created bucket: %s', name); - return callback(null, bucket); + console.log(`Bucket ${bucket.name} created.`); + callback(); }); } -// [END create_bucket] +// [END storage_create_bucket] -// [START list_buckets] -/** - * List all of the authenticated project's buckets. - * - * @param {function} cb The callback function. - */ +// [START storage_list_buckets] function listBuckets (callback) { - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage - storage.getBuckets(function (err, buckets) { + // Instantiates a client + const storageClient = Storage(); + + // Lists all buckets in the current project + storageClient.getBuckets((err, buckets) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Found %d bucket(s)!', buckets.length); - return callback(null, buckets); + console.log('Buckets:'); + buckets.forEach((bucket) => console.log(bucket.name)); + callback(); }); } -// [END list_buckets] +// [END storage_list_buckets] -// [START delete_bucket] -/** - * Deletes the specified bucket. - * - * @param {string} name The name of the bucket to delete. - * @param {function} cb The callback function. - */ -function deleteBucket (name, callback) { - var bucket = storage.bucket(name); +// [START storage_delete_bucket] +function deleteBucket (bucketName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - bucket.delete(function (err) { + // Deletes the bucket + bucket.delete((err) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Deleted bucket: %s', name); - return callback(null); + console.log(`Bucket ${bucket.name} deleted.`); + callback(); }); } -// [END delete_bucket] +// [END storage_delete_bucket] // [END all] // The command-line program -var cli = require('yargs'); -var utils = require('../utils'); +const cli = require(`yargs`); +const noop = require(`../utils`).noop; -var program = module.exports = { +const program = module.exports = { createBucket: createBucket, listBuckets: listBuckets, deleteBucket: deleteBucket, - main: function (args) { + main: (args) => { // Run the command-line program cli.help().strict().parse(args).argv; } @@ -105,21 +101,21 @@ var program = module.exports = { cli .demand(1) - .command('create ', 'Create a new bucket with the given name.', {}, function (options) { - program.createBucket(options.bucket, utils.makeHandler(false)); + .command(`create `, `Creates a new bucket.`, {}, (options) => { + program.createBucket(options.bucket, noop); }) - .command('list', 'List all buckets in the authenticated project.', {}, function () { - program.listBuckets(utils.makeHandler(true, 'name')); + .command(`list`, `Lists all buckets in the current project.`, {}, () => { + program.listBuckets(noop); }) - .command('delete ', 'Delete the specified bucket.', {}, function (options) { - program.deleteBucket(options.bucket, utils.makeHandler(false)); + .command(`delete `, `Deletes a bucket.`, {}, (options) => { + program.deleteBucket(options.bucket, noop); }) - .example('node $0 create my-bucket', 'Create a new bucket named "my-bucket".') - .example('node $0 list', 'List all buckets in the authenticated project.') - .example('node $0 delete my-bucket', 'Delete "my-bucket".') - .wrap(80) + .example(`node $0 create my-bucket`, `Creates a new bucket named "my-bucket".`) + .example(`node $0 list`, `Lists all buckets in the current project.`) + .example(`node $0 delete my-bucket`, `Deletes a bucket named "my-bucket".`) + .wrap(120) .recommendCommands() - .epilogue('For more information, see https://cloud.google.com/storage/docs'); + .epilogue(`For more information, see https://cloud.google.com/storage/docs`); if (module === require.main) { program.main(process.argv.slice(2)); diff --git a/storage/encryption.js b/storage/encryption.js index 83fa5848d4..11c7dd2510 100644 --- a/storage/encryption.js +++ b/storage/encryption.js @@ -1,33 +1,32 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -'use strict'; +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -// [START all] -// [START setup] -// By default, the client will authenticate using the service account file -// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use -// the project specified by the GCLOUD_PROJECT environment variable. See -// https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication -var Storage = require('@google-cloud/storage'); +/** + * This application demonstrates how to perform basic operations on encrypted + * files with the Google Cloud Storage API. + * + * For more information, see the README.md under /storage and the documentation + * at https://cloud.google.com/storage/docs. + */ -// Instantiate a storage client -var storage = Storage(); +'use strict'; -var crypto = require('crypto'); -// [END setup] +const Storage = require('@google-cloud/storage'); +const crypto = require('crypto'); -// [START generate_encryption_key] +// [START storage_generate_encryption_key] /** * Generates a 256 bit (32 byte) AES encryption key and prints the base64 * representation. @@ -39,105 +38,94 @@ var crypto = require('crypto'); * @returns {string} The encryption key. */ function generateEncryptionKey () { - var buffer = crypto.randomBytes(32); - var encodedKey = buffer.toString('base64'); + const buffer = crypto.randomBytes(32); + const encodedKey = buffer.toString('base64'); - console.log('Base 64 encoded encryption key: %s', encodedKey); + console.log(`Base 64 encoded encryption key: ${encodedKey}`); return encodedKey; } -// [END generate_encryption_key] +// [END storage_generate_encryption_key] -// [START upload_encrypted_file] -/** - * Uploads a file to a Google Cloud Storage bucket using a custom encryption key. - * - * The file will be encrypted by Google Cloud Storage and only retrievable using - * the provided encryption key. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The bucket where the file will be uploaded. - * @param {string} options.srcFile The local file to be uploaded. - * @param {string} options.destFile The name of the destination file. - * @param {string} options.key The encryption key. - * @param {function} callback The callback function. - */ -function uploadEncryptedFile (options, callback) { - var bucket = storage.bucket(options.bucket); - var config = { - destination: options.destFile, - encryptionKey: new Buffer(options.key, 'base64') +// [START storage_upload_encrypted_file] +function uploadEncryptedFile (bucketName, srcFileName, destFileName, key, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + const config = { + // The path to which the file should be uploaded, e.g. "file_encrypted.txt" + destination: destFileName, + // Encrypt the file with a customer-supplied key, e.g. "my-secret-key" + encryptionKey: new Buffer(key, 'base64') }; - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - bucket.upload(options.srcFile, config, function (err, file) { + // Encrypts and uploads a local file, e.g. "./local/path/to/file.txt". + // The file will only be retrievable using the key used to upload it. + bucket.upload(srcFileName, config, (err, file) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Uploaded gs://%s/%s', options.bucket, options.destFile); - return callback(null, file); + console.log(`File ${srcFileName} uploaded to ${file.name}.`); + callback(); }); } -// [END upload_encrypted_file] +// [END storage_upload_encrypted_file] -// [START download_encrypted_file] -/** - * Downloads a previously-encrypted file from Google Cloud Storage. - * - * The encryption key provided must be the same key provided when uploading the - * file. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The bucket from which the file will be downloaded. - * @param {string} options.srcFile The name of the file to be downloaded. - * @param {string} options.destFile The local path to which to save the file. - * @param {string} options.key The encryption key. - * @param {function} key The callback function. - */ -function downloadEncryptedFile (options, callback) { - var file = storage.bucket(options.bucket).file(options.srcFile); - var config = { - destination: options.destFile +// [START storage_download_encrypted_file] +function downloadEncryptedFile (bucketName, srcFileName, destFileName, key, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file_encrypted.txt" + const file = bucket.file(srcFileName); + + const config = { + // The path to which the file should be downloaded, e.g. "./file.txt" + destination: destFileName }; - file.setEncryptionKey(new Buffer(options.key, 'base64')); + // Specifies the key that should be used to decrypt the file + file.setEncryptionKey(new Buffer(key, 'base64')); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - file.download(config, function (err) { + // Descrypts and downloads the file. This can only be done with the key used + // to encrypt and upload the file. + file.download(config, (err) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Downloaded gs://%s/%s to %s', options.bucket, options.srcFile, options.destFile); - return callback(null); + console.log(`File ${file.name} downloaded to ${destFileName}.`); + callback(); }); } -// [END download_encrypted_file] +// [END storage_download_encrypted_file] -// [START rotate_encryption_key] -/** - * Performs a key rotation by re-writing an encrypted blob with a new encryption - * key. - * - * @param {function} callback The callback function. - */ +// [START storage_rotate_encryption_key] function rotateEncryptionKey (callback) { callback(new Error('This is currently not available using the Cloud Client Library.')); } -// [END rotate_encryption_key] +// [END storage_rotate_encryption_key] // [END all] // The command-line program -var cli = require('yargs'); -var utils = require('../utils'); +const cli = require(`yargs`); +const noop = require(`../utils`).noop; -var program = module.exports = { +const program = module.exports = { generateEncryptionKey: generateEncryptionKey, uploadEncryptedFile: uploadEncryptedFile, downloadEncryptedFile: downloadEncryptedFile, rotateEncryptionKey: rotateEncryptionKey, - main: function (args) { + main: (args) => { // Run the command-line program cli.help().strict().parse(args).argv; } @@ -145,25 +133,25 @@ var program = module.exports = { cli .demand(1) - .command('generate-encryption-key', 'Generate a sample encryption key.', {}, function () { + .command(`generate-encryption-key`, `Generate a sample encryption key.`, {}, () => { program.generateEncryptionKey(); }) - .command('upload ', 'Upload an encrypted file to a bucket.', {}, function (options) { - program.uploadEncryptedFile(utils.pick(options, ['bucket', 'srcFile', 'destFile', 'key']), utils.makeHandler(false)); + .command(`upload `, `Encrypts and uploads a file.`, {}, (opts) => { + program.uploadEncryptedFile(opts.bucketName, opts.srcFileName, opts.destFileName, opts.key, noop); }) - .command('download ', 'Download an encrypted file from a bucket.', {}, function (options) { - program.downloadEncryptedFile(utils.pick(options, ['bucket', 'srcFile', 'destFile', 'key']), utils.makeHandler(false)); + .command(`download `, `Decrypts and downloads a file.`, {}, (opts) => { + program.downloadEncryptedFile(opts.bucketName, opts.srcFileName, opts.destFileName, opts.key, noop); }) - .command('rotate ', 'Rotate encryption keys for a file.', {}, function () { - program.rotateEncryptionKey(utils.makeHandler()); + .command(`rotate `, `Rotates encryption keys for a file.`, {}, () => { + program.rotateEncryptionKey(noop); }) - .example('node $0 generate-encryption-key', 'Generate a sample encryption key.') - .example('node $0 upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q=', 'Upload "resources/test.txt" to "gs://my-bucket/file_encrypted.txt".') - .example('node $0 download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q=', 'Download "gs://my-bucket/file_encrypted.txt" to "./file.txt".') - .example('node $0 rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q=', 'Rotate encryptiong keys for "gs://my-bucket/file_encrypted.txt".') + .example(`node $0 generate-encryption-key`, `Generate a sample encryption key.`) + .example(`node $0 upload my-bucket ./resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q=`, `Encrypts and uploads "resources/test.txt" to "gs://my-bucket/file_encrypted.txt".`) + .example(`node $0 download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q=`, `Decrypts and downloads "gs://my-bucket/file_encrypted.txt" to "./file.txt".`) + .example(`node $0 rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q=`, `Rotates encryption keys for "gs://my-bucket/file_encrypted.txt".`) .wrap(120) .recommendCommands() - .epilogue('For more information, see https://cloud.google.com/storage/docs'); + .epilogue(`For more information, see https://cloud.google.com/storage/docs`); if (module === require.main) { program.main(process.argv.slice(2)); diff --git a/storage/files.js b/storage/files.js index 32425641b1..d08fddae95 100644 --- a/storage/files.js +++ b/storage/files.js @@ -1,287 +1,329 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This application demonstrates how to perform basic operations on files with + * the Google Cloud Storage API. + * + * For more information, see the README.md under /storage and the documentation + * at https://cloud.google.com/storage/docs. + */ 'use strict'; -// [START all] -// [START setup] -// By default, the client will authenticate using the service account file -// specified by the GOOGLE_APPLICATION_CREDENTIALS environment variable and use -// the project specified by the GCLOUD_PROJECT environment variable. See -// https://googlecloudplatform.github.io/gcloud-node/#/docs/google-cloud/latest/guides/authentication -var Storage = require('@google-cloud/storage'); +const Storage = require('@google-cloud/storage'); -// Instantiate a storage client -var storage = Storage(); -// [END setup] +// [START storage_list_files] +function listFiles (bucketName, callback) { + // Instantiates a client + const storageClient = Storage(); -// [START list_files] -/** - * Lists files in a bucket. - * - * @param {string} name The name of the bucket. - * @param {function} cb The callback function. - */ -function listFiles (name, callback) { - var bucket = storage.bucket(name); + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - bucket.getFiles(function (err, files) { + // Lists files in the bucket + bucket.getFiles((err, files) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Found %d file(s)!', files.length); - return callback(null, files); + console.log('Files:'); + files.forEach((file) => console.log(file.name)); + callback(); }); } -// [END list_files] - -// [START list_files_with_prefix] -/** - * Lists files in a bucket that match a certain prefix. - * - * This can be used to list all blobs in a "folder", e.g. "public/". - * - * The delimiter argument can be used to restrict the results to only the - * "files" in the given "folder". Without the delimiter, the entire tree under - * the prefix is returned. For example, given these blobs: - * - * /a/1.txt - * /a/b/2.txt - * - * If you just specify prefix = '/a', you'll get back: - * - * /a/1.txt - * /a/b/2.txt - * - * However, if you specify prefix='/a' and delimiter='/', you'll get back: - * - * /a/1.txt - * - * @param {object} options Configuration options. - * @param {string} options.bucket The name of the bucket. - * @param {string} options.prefix Filter results to objects whose names begin - * with this prefix. - * @param {string} [options.delimiter] Optional. Results will contain only - * objects whose names, aside from the prefix, do not contain delimiter. - * @param {function} cb The callback function. - */ -function listFilesByPrefix (options, callback) { - var bucket = storage.bucket(options.bucket); - - var config = { - prefix: options.prefix +// [END storage_list_files] + +// [START storage_list_files_with_prefix] +function listFilesByPrefix (bucketName, prefix, delimiter, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + /** + * This can be used to list all blobs in a "folder", e.g. "public/". + * + * The delimiter argument can be used to restrict the results to only the + * "files" in the given "folder". Without the delimiter, the entire tree under + * the prefix is returned. For example, given these blobs: + * + * /a/1.txt + * /a/b/2.txt + * + * If you just specify prefix = '/a', you'll get back: + * + * /a/1.txt + * /a/b/2.txt + * + * However, if you specify prefix='/a' and delimiter='/', you'll get back: + * + * /a/1.txt + */ + const options = { + prefix: prefix }; - if (options.delimiter) { - config.delimiter = options.delimiter; + if (delimiter) { + options.delimiter = delimiter; } - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - bucket.getFiles(config, function (err, files) { + // Lists files in the bucket, filtered by a prefix + bucket.getFiles(options, (err, files) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Found %d file(s)!', files.length); - return callback(null, files); + console.log('Files:'); + files.forEach((file) => console.log(file.name)); + callback(); }); } -// [END list_files_with_prefix] +// [END storage_list_files_with_prefix] -// [START upload_file] -/** - * Upload a file to a bucket. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The name of the bucket. - * @param {string} options.srcFile The name of the file. - * @param {function} cb The callback function. - */ -function uploadFile (options, callback) { - var bucket = storage.bucket(options.bucket); +// [START storage_upload_file] +function uploadFile (bucketName, fileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/bucket - bucket.upload(options.srcFile, function (err, file) { + // Uploads a local file to the bucket, e.g. "./local/path/to/file.txt" + bucket.upload(fileName, (err, file) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Uploaded gs://%s/%s', options.bucket, options.srcFile); - return callback(null, file); + console.log(`File ${file.name} uploaded.`); + callback(); }); } -// [END upload_file] +// [END storage_upload_file] -// [START download_file] -/** - * Download a file from a bucket. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The name of the bucket. - * @param {string} options.srcFile The source file name. - * @param {string} options.destFile The destination file name. - * @param {function} cb The callback function. - */ -function downloadFile (options, callback) { - var file = storage.bucket(options.bucket).file(options.srcFile); +// [START storage_download_file] +function downloadFile (bucketName, srcFileName, destFileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(srcFileName); - var config = { - destination: options.destFile + const options = { + // The path to which the file should be downloaded, e.g. "./file.txt" + destination: destFileName }; - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - file.download(config, function (err) { + // Downloads the file + file.download(options, (err) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Downloaded gs://%s/%s to %s', options.bucket, options.srcFile, options.destFile); - return callback(null); + console.log(`File ${file.name} downloaded to ${destFileName}.`); + callback(); }); } -// [END download_file] +// [END storage_download_file] -// [START delete_file] -/** - * Delete a file from a bucket. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The name of the bucket. - * @param {string} options.file The name of the file to delete. - * @param {function} cb The callback function. - */ -function deleteFile (options, callback) { - var file = storage.bucket(options.bucket).file(options.file); +// [START storage_delete_file] +function deleteFile (bucketName, fileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - file.delete(function (err) { + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + // Deletes the file from the bucket + file.delete((err) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Deleted gs://%s/%s', options.bucket, options.file); - return callback(null); + console.log(`File ${fileName} deleted.`); + callback(); }); } -// [END delete_file] +// [END storage_delete_file] -// [START get_metadata] -/** - * Get a file's metadata. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The name of the bucket. - * @param {string} options.file The name of the file. - * @param {function} cb The callback function. - */ -function getMetadata (options, callback) { - var file = storage.bucket(options.bucket).file(options.file); +// [START storage_get_metadata] +function getMetadata (bucketName, fileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - file.getMetadata(function (err, metadata) { + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + // Gets the metadata for the file + file.getMetadata((err, metadata) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Got metadata for gs://%s/%s', options.bucket, options.file); - return callback(null, metadata); + console.log(`File: ${metadata.name}`); + console.log(`Bucket: ${metadata.bucket}`); + console.log(`Storage class: ${metadata.storageClass}`); + console.log(`ID: ${metadata.id}`); + console.log(`Size: ${metadata.size}`); + console.log(`Updated: ${metadata.updated}`); + console.log(`Generation: ${metadata.generation}`); + console.log(`Metageneration: ${metadata.metageneration}`); + console.log(`Etag: ${metadata.etag}`); + console.log(`Owner: ${metadata.owner}`); + console.log(`Component count: ${metadata.component_count}`); + console.log(`Crc32c: ${metadata.crc32c}`); + console.log(`md5Hash: ${metadata.md5Hash}`); + console.log(`Cache-control: ${metadata.cacheControl}`); + console.log(`Content-type: ${metadata.contentType}`); + console.log(`Content-disposition: ${metadata.contentDisposition}`); + console.log(`Content-encoding: ${metadata.contentEncoding}`); + console.log(`Content-language: ${metadata.contentLanguage}`); + console.log(`Metadata: ${metadata.metadata}`); + callback(); }); } -// [END get_metadata] +// [END storage_get_metadata] -// [START public] -/** - * Make a file public. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The name of the bucket. - * @param {string} options.file The name of the file to make public. - * @param {function} cb The callback function. - */ -function makePublic (options, callback) { - var file = storage.bucket(options.bucket).file(options.file); +// [START storage_make_public] +function makePublic (bucketName, fileName, callback) { + // Instantiates a client + const storageClient = Storage(); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - file.makePublic(function (err) { + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + // Makes the file public + file.makePublic((err) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Made gs://%s/%s public!', options.bucket, options.file); - return callback(null); + console.log(`File ${file.name} is now public.`); + callback(); }); } -// [END public] +// [END storage_make_public] -// [START move_file] -/** - * Move a file to a new location within the same bucket, i.e. rename the file. - * - * @param {object} options Configuration options. - * @param {string} options.bucket The name of the bucket. - * @param {string} options.srcFile The source file name. - * @param {string} options.destFile The destination file name. - * @param {function} cb The callback function. - */ -function moveFile (options, callback) { - var file = storage.bucket(options.bucket).file(options.srcFile); +// [START storage_generate_signed_url] +function generateSignedUrl (bucketName, fileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(fileName); + + // These options will allow temporary read access to the file + const options = { + action: 'read', + expires: '03-17-2025' + }; - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - file.move(options.destFile, function (err, file) { + // Get a signed URL for the file + file.getSignedUrl(options, (err, url) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Renamed gs://%s/%s to gs://%s/%s', options.bucket, options.srcFile, options.bucket, options.destFile); - return callback(null, file); + console.log(`The signed url for ${file.name} is ${url}.`); + callback(); }); } -// [END move_file] +// [END storage_generate_signed_url] -// [START copy_file] -/** - * Copy a file to a new bucket with a new name. - * - * @param {object} options Configuration options. - * @param {string} options.srcBucket The name of the bucket. - * @param {string} options.srcFile The source file name. - * @param {string} options.destBucket The destination bucket name. - * @param {string} options.destFile The destination file name. - * @param {function} cb The callback function. - */ -function copyFile (options, callback) { - var file = storage.bucket(options.srcBucket).file(options.srcFile); - var copy = storage.bucket(options.destBucket).file(options.destFile); +// [START storage_move_file] +function moveFile (bucketName, srcFileName, destFileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(bucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(srcFileName); + + // Moves the file within the bucket + file.move(destFileName, (err) => { + if (err) { + callback(err); + return; + } + + console.log(`File ${file.name} moved to ${destFileName}.`); + callback(); + }); +} +// [END storage_move_file] + +// [START storage_copy_file] +function copyFile (srcBucketName, srcFileName, destBucketName, destFileName, callback) { + // Instantiates a client + const storageClient = Storage(); + + // References an existing bucket, e.g. "my-bucket" + const bucket = storageClient.bucket(srcBucketName); + + // References an existing file, e.g. "file.txt" + const file = bucket.file(srcFileName); - // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/latest/storage/file - file.copy(copy, function (err, file) { + // References another existing bucket, e.g. "my-other-bucket" + const destBucket = storageClient.bucket(destBucketName); + + // Creates a reference to a destination file, e.g. "file.txt" + const destFile = destBucket.file(destFileName); + + // Copies the file to the other bucket + file.copy(destFile, (err, file) => { if (err) { - return callback(err); + callback(err); + return; } - console.log('Copied gs://%s/%s to gs://%s/%s', options.srcBucket, options.srcFile, options.destBucket, options.destFile); - return callback(null, file); + console.log(`File ${srcFileName} copied to ${file.name} in ${destBucket.name}.`); + callback(); }); } -// [END copy_file] -// [END all] +// [END storage_copy_file] // The command-line program -var cli = require('yargs'); -var utils = require('../utils'); +const cli = require(`yargs`); +const noop = require(`../utils`).noop; -var program = module.exports = { +const program = module.exports = { listFiles: listFiles, listFilesByPrefix: listFilesByPrefix, uploadFile: uploadFile, @@ -289,9 +331,10 @@ var program = module.exports = { deleteFile: deleteFile, getMetadata: getMetadata, makePublic: makePublic, + generateSignedUrl: generateSignedUrl, moveFile: moveFile, copyFile: copyFile, - main: function (args) { + main: (args) => { // Run the command-line program cli.help().strict().parse(args).argv; } @@ -299,59 +342,49 @@ var program = module.exports = { cli .demand(1) - .command('list [options]', 'List files in a bucket, optionally filtering by a prefix.', { - prefix: { - alias: 'p', - requiresArg: true, - type: 'string', - description: 'Filter files by a prefix.' - }, - delimiter: { - alias: 'd', - requiresArg: true, - type: 'string', - description: 'Specify a delimiter.' - } - }, function (options) { - if (options.prefix) { - program.listFilesByPrefix(utils.pick(options, ['bucket', 'prefix', 'delimiter']), utils.makeHandler(true, 'name')); + .command(`list [prefix] [delimiter]`, `Lists files in a bucket, optionally filtering by a prefix.`, {}, (opts) => { + if (opts.prefix) { + program.listFilesByPrefix(opts.bucketName, opts.prefix, opts.delimiter, noop); } else { - program.listFiles(options.bucket, utils.makeHandler(true, 'name')); + program.listFiles(opts.bucketName, noop); } }) - .command('upload ', 'Upload a local file to a bucket.', {}, function (options) { - program.uploadFile(utils.pick(options, ['bucket', 'srcFile']), utils.makeHandler(false)); + .command(`upload `, `Uploads a local file to a bucket.`, {}, (opts) => { + program.uploadFile(opts.bucketName, opts.srcFileName, noop); + }) + .command(`download `, `Downloads a file from a bucket.`, {}, (opts) => { + program.downloadFile(opts.bucketName, opts.srcFileName, opts.destFileName, noop); }) - .command('download ', 'Download a file from a bucket.', {}, function (options) { - program.downloadFile(utils.pick(options, ['bucket', 'srcFile', 'destFile']), utils.makeHandler(false)); + .command(`delete `, `Deletes a file from a bucket.`, {}, (opts) => { + program.deleteFile(opts.bucketName, opts.fileName, noop); }) - .command('delete ', 'Delete a file from a bucket.', {}, function (options) { - program.deleteFile(utils.pick(options, ['bucket', 'file']), utils.makeHandler(false)); + .command(`get-metadata `, `Gets the metadata for a file.`, {}, (opts) => { + program.getMetadata(opts.bucketName, opts.fileName, noop); }) - .command('getMetadata ', 'Get metadata for a file in a bucket.', {}, function (options) { - program.getMetadata(utils.pick(options, ['bucket', 'file']), utils.makeHandler()); + .command(`make-public `, `Makes a file public.`, {}, (opts) => { + program.makePublic(opts.bucketName, opts.fileName, noop); }) - .command('makePublic ', 'Make a file public in a bucket.', {}, function (options) { - program.makePublic(utils.pick(options, ['bucket', 'file']), utils.makeHandler(false)); + .command(`generate-signed-url `, `Generates a signed URL for a file.`, {}, (opts) => { + program.generateSignedUrl(opts.bucketName, opts.fileName, noop); }) - .command('move ', 'Move a file to a new location within the same bucket, i.e. rename the file.', {}, function (options) { - program.moveFile(utils.pick(options, ['bucket', 'srcFile', 'destFile']), utils.makeHandler(false)); + .command(`move `, `Moves a file to a new location within the same bucket, i.e. rename the file.`, {}, (opts) => { + program.moveFile(opts.bucketName, opts.srcFileName, opts.destFileName, noop); }) - .command('copy ', 'Copy a file in a bucket to another bucket.', {}, function (options) { - program.copyFile(utils.pick(options, ['srcBucket', 'srcFile', 'destBucket', 'destFile']), utils.makeHandler(false)); + .command(`copy `, `Copies a file in a bucket to another bucket.`, {}, (opts) => { + program.copyFile(opts.srcBucketName, opts.srcFileName, opts.destBucketName, opts.destFileName, noop); }) - .example('node $0 list my-bucket', 'List files in "my-bucket".') - .example('node $0 list my-bucket -p public/', 'List files in "my-bucket" filtered by prefix "public/".') - .example('node $0 upload my-bucket ./file.txt', 'Upload "./file.txt" to "my-bucket".') - .example('node $0 download my-bucket file.txt ./file.txt', 'Download "gs://my-bucket/file.txt" to "./file.txt".') - .example('node $0 delete my-bucket file.txt', 'Delete "gs://my-bucket/file.txt".') - .example('node $0 getMetadata my-bucket file.txt', 'Get metadata for "gs://my-bucket/file.txt".') - .example('node $0 makePublic my-bucket file.txt', 'Make "gs://my-bucket/file.txt" public.') - .example('node $0 move my-bucket file.txt file2.txt', 'Rename "gs://my-bucket/file.txt" to "gs://my-bucket/file2.txt".') - .example('node $0 copy my-bucket file.txt my-other-bucket file.txt', 'Copy "gs://my-bucket/file.txt" to "gs://my-other-bucket/file.txt".') - .wrap(100) + .example(`node $0 list my-bucket`, `Lists files in "my-bucket".`) + .example(`node $0 list my-bucket public/`, `Lists files in "my-bucket" filtered by prefix "public/".`) + .example(`node $0 upload my-bucket ./file.txt`, `Uploads "./file.txt" to "my-bucket".`) + .example(`node $0 download my-bucket file.txt ./file.txt`, `Downloads "gs://my-bucket/file.txt" to "./file.txt".`) + .example(`node $0 delete my-bucket file.txt`, `Deletes "gs://my-bucket/file.txt".`) + .example(`node $0 get-metadata my-bucket file.txt`, `Gets the metadata for "gs://my-bucket/file.txt".`) + .example(`node $0 make-public my-bucket file.txt`, `Makes "gs://my-bucket/file.txt" public.`) + .example(`node $0 move my-bucket file.txt file2.txt`, `Renames "gs://my-bucket/file.txt" to "gs://my-bucket/file2.txt".`) + .example(`node $0 copy my-bucket file.txt my-other-bucket file.txt`, `Copies "gs://my-bucket/file.txt" to "gs://my-other-bucket/file.txt".`) + .wrap(120) .recommendCommands() - .epilogue('For more information, see https://cloud.google.com/storage/docs'); + .epilogue(`For more information, see https://cloud.google.com/storage/docs`); if (module === require.main) { program.main(process.argv.slice(2)); diff --git a/storage/package.json b/storage/package.json index d13d9b8eb9..c4588c6195 100644 --- a/storage/package.json +++ b/storage/package.json @@ -5,13 +5,13 @@ "license": "Apache Version 2.0", "author": "Google Inc.", "scripts": { - "test": "mocha -R spec -t 120000 --require intelli-espower-loader ../test/_setup.js test/*.test.js", - "system-test": "mocha -R spec -t 120000 --require intelli-espower-loader ../system-test/_setup.js system-test/*.test.js" + "test": "mocha -R spec -t 120000 ../test/_setup.js test/*.test.js", + "system-test": "mocha -R spec -t 120000 ../system-test/_setup.js system-test/*.test.js" }, "dependencies": { - "@google-cloud/storage": "^0.1.1", - "googleapis": "^12.2.0", - "moment": "^2.14.1", + "@google-cloud/storage": "^0.2.0", + "googleapis": "^13.0.0", + "moment": "^2.15.1", "yargs": "^6.0.0" }, "devDependencies": { diff --git a/storage/system-test/acl.test.js b/storage/system-test/acl.test.js index 12cddde3f0..78c98878fc 100644 --- a/storage/system-test/acl.test.js +++ b/storage/system-test/acl.test.js @@ -1,237 +1,111 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var path = require('path'); -var Storage = require('@google-cloud/storage'); -var uuid = require('node-uuid'); -var program = require('../acl'); - -var storage = Storage(); -var bucketName = 'nodejs-docs-samples-test-' + uuid.v4(); -var fileName = 'test.txt'; -var entity = 'allAuthenticatedUsers'; -var role = 'READER'; -var filePath = path.join(__dirname, '../resources', fileName); - -var expected = { - entity: entity, - role: role -}; - -describe('storage:acl', function () { - before(function (done) { - storage.createBucket(bucketName, function (err, bucket) { - if (err) { - return done(err); - } +const storage = require(`@google-cloud/storage`)(); +const uuid = require(`node-uuid`); +const path = require(`path`); +const run = require(`../../utils`).run; + +const cwd = path.join(__dirname, `..`); +const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; +const userEmail = `00b4903a973860a50828a620e09dde96aae6122ca4f0835bd469384659f1a5b8`; +const fileName = `test.txt`; +const filePath = path.join(__dirname, `../resources`, fileName); +const cmd = `node acl.js`; + +describe('storage:acl', () => { + before((done) => { + storage.createBucket(bucketName, (err, bucket) => { + assert.ifError(err); bucket.upload(filePath, done); }); }); - after(function (done) { - storage.bucket(bucketName).deleteFiles({ force: true }, function (err) { - if (err) { - return done(err); - } - storage.bucket(bucketName).delete(done); + after((done) => { + storage.bucket(bucketName).file(fileName).delete(() => { + // Ignore error + setTimeout(() => { + storage.bucket(bucketName).delete(() => { + // Ignore error + done(); + }); + }, 2000); }); }); - describe('add', function () { - it('should add access controls to a bucket', function (done) { - program.addAccessControl({ - bucket: bucketName, - entity: entity, - role: role - }, function (err, aclObject) { - assert.ifError(err); - assert.deepEqual(aclObject, expected); - done(); - }); - }); - - it('should add "default" access controls to a bucket', function (done) { - program.addAccessControl({ - bucket: bucketName, - entity: entity, - role: role, - default: true - }, function (err, aclObject) { - assert.ifError(err); - assert.deepEqual(aclObject, expected); - done(); - }); - }); - - it('should add access controls to a file', function (done) { - program.addAccessControl({ - bucket: bucketName, - file: fileName, - entity: entity, - role: role - }, function (err, aclObject) { - assert.ifError(err); - assert.ifError(err); - assert.deepEqual(aclObject, expected); - setTimeout(done, 2000); // Make sure changes have time to take effect - }); - }); + it(`should print acl for a bucket`, () => { + const output = run(`${cmd} print-bucket-acl ${bucketName}`, cwd); + assert.equal(/OWNER: project-editors-/.test(output), true); + assert.equal(/OWNER: project-owners-/.test(output), true); + assert.equal(/READER: project-viewers-/.test(output), true); }); - describe('get', function () { - it('should get all access controls for a bucket', function (done) { - program.getAccessControl({ - bucket: bucketName - }, function (err, aclObjects) { - assert.ifError(err); - assert(Array.isArray(aclObjects)); - assert(aclObjects.length > 1); - var matchesExpected = aclObjects.filter(function (aclObject) { - return aclObject.entity === entity && aclObject.role === role; - }); - assert.equal(matchesExpected.length, 1, 'Recently added aclObject should be in list'); - done(); - }); - }); - - it('should get an entity\'s access controls for a bucket', function (done) { - program.getAccessControl({ - bucket: bucketName, - entity: entity - }, function (err, aclObject) { - assert.ifError(err); - assert.deepEqual(aclObject, expected); - done(); - }); - }); - - it('should get all "default" access controls for a bucket', function (done) { - program.getAccessControl({ - bucket: bucketName, - default: true - }, function (err, aclObjects) { - assert.ifError(err); - assert(Array.isArray(aclObjects)); - assert(aclObjects.length > 1); - var matchesExpected = aclObjects.filter(function (aclObject) { - return aclObject.entity === entity && aclObject.role === role; - }); - assert.equal(matchesExpected.length, 1, 'Recently added aclObject should be in list'); - done(); - }); - }); - - it('should get an entity\'s "default" access controls for a bucket', function (done) { - program.getAccessControl({ - bucket: bucketName, - entity: entity, - default: true - }, function (err, aclObject) { - assert.ifError(err); - assert.deepEqual(aclObject, expected); - done(); - }); + it(`should print a user's acl for a bucket`, (done) => { + storage.bucket(bucketName).acl.readers.addUser(userEmail, (err) => { + assert.ifError(err); + const output = run(`${cmd} print-bucket-acl-for-user ${bucketName} ${userEmail}`, cwd); + assert.equal(output, `READER: user-${userEmail}`); + storage.bucket(bucketName).acl.readers.deleteUser(userEmail, done); }); + }); - it('should get all access controls for a file', function (done) { - program.getAccessControl({ - bucket: bucketName, - file: fileName - }, function (err, aclObjects) { - assert.ifError(err); - assert(Array.isArray(aclObjects)); - assert(aclObjects.length > 1); - var matchesExpected = aclObjects.filter(function (aclObject) { - return aclObject.entity === entity && aclObject.role === role; - }); - assert.equal(matchesExpected.length, 1, 'Recently added aclObject should be in list'); - done(); - }); - }); + it(`should add a user as an owner on a bucket`, () => { + const output = run(`${cmd} add-bucket-owner ${bucketName} ${userEmail}`, cwd); + assert.equal(output, `Added user ${userEmail} as an owner on bucket ${bucketName}.`); + }); - it('should get an entity\'s access controls for a file', function (done) { - program.getAccessControl({ - bucket: bucketName, - file: fileName, - entity: entity - }, function (err, aclObject) { - assert.ifError(err); - assert.deepEqual(aclObject, expected); - done(); - }); - }); + it(`should remove a user from a bucket`, () => { + const output = run(`${cmd} remove-bucket-owner ${bucketName} ${userEmail}`, cwd); + assert.equal(output, `Removed user ${userEmail} from bucket ${bucketName}.`); }); - describe('delete', function () { - it('should delete an entity\'s access controls from a file', function (done) { - program.deleteAccessControl({ - bucket: bucketName, - file: fileName, - entity: entity - }, function (err) { - assert.ifError(err); + it(`should add a user as a default owner on a bucket`, () => { + const output = run(`${cmd} add-bucket-default-owner ${bucketName} ${userEmail}`, cwd); + assert.equal(output, `Added user ${userEmail} as an owner on bucket ${bucketName}.`); + }); - program.getAccessControl({ - bucket: bucketName, - file: fileName, - entity: entity - }, function (err, aclObject) { - assert(err); - assert.equal(err.message, 'Not Found'); - done(); - }); - }); - }); + it(`should remove a default user from a bucket`, () => { + const output = run(`${cmd} remove-bucket-default-owner ${bucketName} ${userEmail}`, cwd); + assert.equal(output, `Removed user ${userEmail} from bucket ${bucketName}.`); + }); - it('should delete an entity\'s access controls from a bucket', function (done) { - program.deleteAccessControl({ - bucket: bucketName, - entity: entity - }, function (err, aclObject) { - assert.ifError(err); + it(`should print acl for a file`, () => { + const output = run(`${cmd} print-file-acl ${bucketName} ${fileName}`, cwd); + assert.equal(/OWNER: project-editors-/.test(output), true); + assert.equal(/OWNER: project-owners-/.test(output), true); + assert.equal(/READER: project-viewers-/.test(output), true); + }); - program.getAccessControl({ - bucket: bucketName, - entity: entity - }, function (err, aclObject) { - assert(err); - assert.equal(err.message, 'Not Found'); - done(); - }); - }); + it(`should print a user's acl for a file`, (done) => { + storage.bucket(bucketName).file(fileName).acl.readers.addUser(userEmail, (err) => { + assert.ifError(err); + const output = run(`${cmd} print-file-acl-for-user ${bucketName} ${fileName} ${userEmail}`, cwd); + assert.equal(output, `READER: user-${userEmail}`); + storage.bucket(bucketName).file(fileName).acl.readers.deleteUser(userEmail, done); }); + }); - it('should delete an entity\'s "default" access controls from a bucket', function (done) { - program.deleteAccessControl({ - bucket: bucketName, - entity: entity, - default: true - }, function (err, aclObject) { - assert.ifError(err); + it(`should add a user as an owner on a bucket`, () => { + const output = run(`${cmd} add-file-owner ${bucketName} ${fileName} ${userEmail}`, cwd); + assert.equal(output, `Added user ${userEmail} as an owner on file ${fileName}.`); + }); - program.getAccessControl({ - bucket: bucketName, - file: fileName, - entity: entity, - default: true - }, function (err, aclObject) { - assert(err); - assert.equal(err.message, 'Not Found'); - done(); - }); - }); - }); + it(`should remove a user from a bucket`, () => { + const output = run(`${cmd} remove-file-owner ${bucketName} ${fileName} ${userEmail}`, cwd); + assert.equal(output, `Removed user ${userEmail} from file ${fileName}.`); }); }); diff --git a/storage/system-test/buckets.test.js b/storage/system-test/buckets.test.js index d89312b08c..f53ba56ee4 100644 --- a/storage/system-test/buckets.test.js +++ b/storage/system-test/buckets.test.js @@ -1,53 +1,64 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var uuid = require('node-uuid'); -var program = require('../buckets'); -var bucketName = 'nodejs-docs-samples-test-' + uuid.v4(); +const storage = require(`@google-cloud/storage`)(); +const uuid = require(`node-uuid`); +const path = require(`path`); +const run = require(`../../utils`).run; -describe('storage:buckets', function () { - describe('create', function () { - it('should create a bucket', function (done) { - program.createBucket(bucketName, function (err, bucket) { - assert.ifError(err); - assert.equal(bucket.name, bucketName); - assert(console.log.calledWith('Created bucket: %s', bucketName)); - setTimeout(done, 2000); - }); +const cwd = path.join(__dirname, `..`); +const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; +const cmd = `node buckets.js`; + +describe('storage:buckets', () => { + after((done) => { + storage.bucket(bucketName).delete(() => { + // Ignore any error + done(); }); }); - describe('list', function () { - it('should list buckets', function (done) { - program.listBuckets(function (err, buckets) { - assert.ifError(err); - assert(Array.isArray(buckets)); - assert(buckets.length > 0); - assert(console.log.calledWith('Found %d bucket(s)!', buckets.length)); - setTimeout(done, 2000); - }); + it(`should create a bucket`, (done) => { + const output = run(`${cmd} create ${bucketName}`, cwd); + assert.equal(output, `Bucket ${bucketName} created.`); + storage.bucket(bucketName).exists((err, exists) => { + assert.ifError(err); + assert.equal(exists, true); + done(); }); }); - describe('delete', function () { - it('should delete a bucket', function (done) { - program.deleteBucket(bucketName, function (err, apiResponse) { - assert.ifError(err); - assert(console.log.calledWith('Deleted bucket: %s', bucketName)); - done(); - }); + it(`should list buckets`, (done) => { + // Listing is eventually consistent. Give the indexes time to update. + setTimeout(() => { + const output = run(`${cmd} list`, cwd); + assert.notEqual(output.indexOf(`Buckets:`), -1); + assert.notEqual(output.indexOf(bucketName), -1); + done(); + }, 5000); + }); + + it(`should delete a bucket`, (done) => { + const output = run(`${cmd} delete ${bucketName}`, cwd); + assert.equal(output, `Bucket ${bucketName} deleted.`); + storage.bucket(bucketName).exists((err, exists) => { + assert.ifError(err); + assert.equal(exists, false); + done(); }); }); }); diff --git a/storage/system-test/encryption.test.js b/storage/system-test/encryption.test.js index 5d8d3de41c..c654a3c6dd 100644 --- a/storage/system-test/encryption.test.js +++ b/storage/system-test/encryption.test.js @@ -1,41 +1,46 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var fs = require('fs'); -var path = require('path'); -var Storage = require('@google-cloud/storage'); -var uuid = require('node-uuid'); -var program = require('../encryption'); +const fs = require('fs'); +const path = require('path'); +const program = require('../encryption'); +const run = require(`../../utils`).run; +const storage = require('@google-cloud/storage')(); +const uuid = require('node-uuid'); -var storage = Storage(); -var bucketName = 'nodejs-docs-samples-test-' + uuid.v4(); -var fileName = 'test.txt'; -var filePath = path.join(__dirname, '../resources', fileName); -var downloadFilePath = path.join(__dirname, '../resources/downloaded.txt'); +const cwd = path.join(__dirname, `..`); +const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; +const cmd = `node encryption.js`; -describe('storage:encryption', function () { - var key; +const fileName = `test.txt`; +const filePath = path.join(__dirname, `../resources`, fileName); +const downloadFilePath = path.join(__dirname, `../resources/downloaded.txt`); - before(function (done) { +describe('storage:encryption', () => { + let key; + + before((done) => { // Create an encryption key to use throughout the test key = program.generateEncryptionKey(); // Create a test bucket storage.createBucket(bucketName, done); }); - after(function (done) { + after((done) => { try { // Delete the downloaded file fs.unlinkSync(downloadFilePath); @@ -43,51 +48,43 @@ describe('storage:encryption', function () { console.log(err); } // Delete any files that were uploaded - storage.bucket(bucketName).deleteFiles({ force: true }, function (err) { - if (err) { - return done(err); - } + storage.bucket(bucketName).deleteFiles({ force: true }, (err) => { + assert.ifError(err); // Delete the test bucket storage.bucket(bucketName).delete(done); }); }); - describe('uploadEncryptedFile', function () { - it('should upload a file', function (done) { - var options = { - bucket: bucketName, - srcFile: filePath, - destFile: fileName, - key: key - }; + it(`should generate a key`, () => { + const output = run(`${cmd} generate-encryption-key`, cwd); + assert.notEqual(output.indexOf(`Base 64 encoded encryption key:`), -1); + }); - program.uploadEncryptedFile(options, function (err, file) { - assert.ifError(err); - assert(file); - assert.equal(file.name, fileName); - assert(console.log.calledWith('Uploaded gs://%s/%s', options.bucket, options.destFile)); - done(); - }); + it(`should upload a file`, (done) => { + const output = run(`${cmd} upload ${bucketName} ${filePath} ${fileName} ${key}`, cwd); + assert.equal(output, `File ${filePath} uploaded to ${fileName}.`); + storage.bucket(bucketName).file(fileName).exists((err, exists) => { + assert.ifError(err); + assert.equal(exists, true); + done(); }); }); - describe('downloadEncryptedFile', function () { - it('should download a file', function (done) { - var options = { - bucket: bucketName, - srcFile: fileName, - destFile: downloadFilePath, - key: key - }; - - program.downloadEncryptedFile(options, function (err) { - assert.ifError(err); - assert.doesNotThrow(function () { - fs.statSync(downloadFilePath); - }); - assert(console.log.calledWith('Downloaded gs://%s/%s to %s', options.bucket, options.srcFile, options.destFile)); - done(); + it(`should download a file`, (done) => { + const output = run(`${cmd} download ${bucketName} ${fileName} ${downloadFilePath} ${key}`, cwd); + assert.equal(output, `File ${fileName} downloaded to ${downloadFilePath}.`); + storage.bucket(bucketName).file(fileName).exists((err, exists) => { + assert.ifError(err); + assert.doesNotThrow(() => { + fs.statSync(downloadFilePath); }); + done(); }); }); + + it(`should rotate keys`, () => { + assert.throws(() => { + run(`${cmd} rotate ${bucketName} ${fileName} ${key} ${key}`, cwd); + }, Error, `This is currently not available using the Cloud Client Library.`); + }); }); diff --git a/storage/system-test/files.test.js b/storage/system-test/files.test.js index 5e0d2f9ee1..02e55c6463 100644 --- a/storage/system-test/files.test.js +++ b/storage/system-test/files.test.js @@ -1,214 +1,133 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var fs = require('fs'); -var path = require('path'); -var Storage = require('@google-cloud/storage'); -var uuid = require('node-uuid'); -var filesExample = require('../files'); - -var storage = Storage(); -var bucketName = 'nodejs-docs-samples-test-' + uuid.v4(); -var fileName = 'test.txt'; -var movedFileName = 'test2.txt'; -var copiedFileName = 'test3.txt'; -var filePath = path.join(__dirname, '../resources', fileName); -var downloadFilePath = path.join(__dirname, '../resources/downloaded.txt'); - -describe('storage:files', function () { - before(function (done) { +const fs = require(`fs`); +const storage = require(`@google-cloud/storage`)(); +const uuid = require(`node-uuid`); +const path = require(`path`); +const run = require(`../../utils`).run; + +const cwd = path.join(__dirname, `..`); +const bucketName = `nodejs-docs-samples-test-${uuid.v4()}`; +const fileName = `test.txt`; +const movedFileName = `test2.txt`; +const copiedFileName = `test3.txt`; +const filePath = path.join(__dirname, `../resources`, fileName); +const downloadFilePath = path.join(__dirname, `../resources/downloaded.txt`); +const cmd = `node files.js`; + +describe('storage:files', () => { + before((done) => { storage.createBucket(bucketName, done); }); - after(function (done) { + after((done) => { try { fs.unlinkSync(downloadFilePath); } catch (err) { console.log(err); } - storage.bucket(bucketName).deleteFiles({ force: true }, function (err) { - if (err) { - return done(err); - } - storage.bucket(bucketName).delete(done); + storage.bucket(bucketName).deleteFiles({ force: true }, (err) => { + assert.ifError(err); + setTimeout(() => storage.bucket(bucketName).delete(done), 2000); }); }); - describe('uploadFile', function () { - it('should upload a file', function (done) { - var options = { - bucket: bucketName, - srcFile: filePath - }; - - filesExample.uploadFile(options, function (err, file) { - assert.ifError(err); - assert(file); - assert.equal(file.name, fileName); - assert(console.log.calledWith('Uploaded gs://%s/%s', options.bucket, options.srcFile)); - done(); - }); + it('should upload a file', (done) => { + const output = run(`${cmd} upload ${bucketName} ${filePath}`, cwd); + assert.equal(output, `File ${fileName} uploaded.`); + storage.bucket(bucketName).file(fileName).exists((err, exists) => { + assert.ifError(err); + assert.equal(exists, true); + done(); }); }); - describe('downloadFile', function () { - it('should download a file', function (done) { - var options = { - bucket: bucketName, - srcFile: fileName, - destFile: downloadFilePath - }; - - filesExample.downloadFile(options, function (err) { - assert.ifError(err); - assert.doesNotThrow(function () { - fs.statSync(downloadFilePath); - }); - assert(console.log.calledWith('Downloaded gs://%s/%s to %s', options.bucket, options.srcFile, options.destFile)); - done(); - }); - }); + it('should download a file', () => { + const output = run(`${cmd} download ${bucketName} ${fileName} ${downloadFilePath}`, cwd); + assert.equal(output, `File ${fileName} downloaded to ${downloadFilePath}.`); + assert.doesNotThrow(() => fs.statSync(downloadFilePath)); }); - describe('moveFile', function () { - it('should move a file', function (done) { - var options = { - bucket: bucketName, - srcFile: fileName, - destFile: movedFileName - }; - - filesExample.moveFile(options, function (err, file) { - assert.ifError(err); - assert.equal(file.name, movedFileName); - assert(console.log.calledWith('Renamed gs://%s/%s to gs://%s/%s', options.bucket, options.srcFile, options.bucket, options.destFile)); - - // Listing is eventually consistent, give the index time to update - setTimeout(done, 5000); - }); + it('should move a file', (done) => { + const output = run(`${cmd} move ${bucketName} ${fileName} ${movedFileName}`, cwd); + assert.equal(output, `File ${fileName} moved to ${movedFileName}.`); + storage.bucket(bucketName).file(movedFileName).exists((err, exists) => { + assert.ifError(err); + assert.equal(exists, true); + done(); }); }); - describe('listFiles', function () { - it('should list files', function (done) { - filesExample.listFiles(bucketName, function (err, files) { - assert.ifError(err); - assert(Array.isArray(files)); - assert.equal(files.length, 1); - assert.equal(files[0].name, movedFileName); - assert(console.log.calledWith('Found %d file(s)!', files.length)); - done(); - }); + it('should copy a file', (done) => { + const output = run(`${cmd} copy ${bucketName} ${movedFileName} ${bucketName} ${copiedFileName}`, cwd); + assert.equal(output, `File ${movedFileName} copied to ${copiedFileName} in ${bucketName}.`); + storage.bucket(bucketName).file(copiedFileName).exists((err, exists) => { + assert.ifError(err); + assert.equal(exists, true); + done(); }); }); - describe('copyFile', function () { - it('should copy a file', function (done) { - var options = { - srcBucket: bucketName, - srcFile: movedFileName, - destBucket: bucketName, - destFile: copiedFileName - }; - - filesExample.copyFile(options, function (err, file) { - assert.ifError(err); - assert.equal(file.name, copiedFileName); - assert(console.log.calledWith('Copied gs://%s/%s to gs://%s/%s', options.srcBucket, options.srcFile, options.destBucket, options.destFile)); - - // Listing is eventually consistent, give the index time to update - setTimeout(done, 5000); - }); - }); + it('should list files', (done) => { + // Listing is eventually consistent, give the indexes time to update + setTimeout(() => { + const output = run(`${cmd} list ${bucketName}`, cwd); + assert.notEqual(output.indexOf(`Files:`), -1); + assert.notEqual(output.indexOf(movedFileName), -1); + assert.notEqual(output.indexOf(copiedFileName), -1); + done(); + }, 5000); }); - describe('listFilesByPrefix', function () { - it('should list files by a prefix', function (done) { - var options = { - bucket: bucketName, - prefix: 'test' - }; - - filesExample.listFilesByPrefix(options, function (err, files) { - assert.ifError(err); - assert(Array.isArray(files)); - assert.equal(files.length, 2); - assert.equal(files[0].name, movedFileName); - assert.equal(files[1].name, copiedFileName); - assert(console.log.calledWith('Found %d file(s)!', files.length)); - - options = { - bucket: bucketName, - prefix: 'foo' - }; - - filesExample.listFilesByPrefix(options, function (err, files) { - assert.ifError(err); - assert(Array.isArray(files)); - assert.equal(files.length, 0); - assert(console.log.calledWith('Found %d file(s)!', files.length)); - done(); - }); - }); - }); + it('should list files by a prefix', () => { + let output = run(`${cmd} list ${bucketName} test "/"`, cwd); + assert.notEqual(output.indexOf(`Files:`), -1); + assert.notEqual(output.indexOf(movedFileName), -1); + assert.notEqual(output.indexOf(copiedFileName), -1); + output = run(`${cmd} list ${bucketName} foo`, cwd); + assert.notEqual(output.indexOf(`Files:`), -1); + assert.equal(output.indexOf(movedFileName), -1); + assert.equal(output.indexOf(copiedFileName), -1); }); - describe('makePublic', function () { - it('should make a file public', function (done) { - var options = { - bucket: bucketName, - file: copiedFileName - }; - - filesExample.makePublic(options, function (err) { - assert.ifError(err); - assert(console.log.calledWith('Made gs://%s/%s public!', options.bucket, options.file)); - done(); - }); - }); + it('should make a file public', () => { + const output = run(`${cmd} make-public ${bucketName} ${copiedFileName}`, cwd); + assert.equal(output, `File ${copiedFileName} is now public.`); }); - describe('getMetadata', function () { - it('should get metadata for a file', function (done) { - var options = { - bucket: bucketName, - file: copiedFileName - }; - - filesExample.getMetadata(options, function (err, metadata) { - assert.ifError(err); - assert(metadata); - assert.equal(metadata.name, copiedFileName); - assert(console.log.calledWith('Got metadata for gs://%s/%s', options.bucket, options.file)); - done(); - }); - }); + it('should generate a signed URL for a file', () => { + const output = run(`${cmd} generate-signed-url ${bucketName} ${copiedFileName}`, cwd); + assert.notEqual(output.indexOf(`The signed url for ${copiedFileName} is `), -1); }); - describe('deleteFile', function () { - it('should delete a file', function (done) { - var options = { - bucket: bucketName, - file: copiedFileName - }; + it('should get metadata for a file', () => { + const output = run(`${cmd} get-metadata ${bucketName} ${copiedFileName}`, cwd); + assert.notEqual(output.indexOf(`File: ${copiedFileName}`), -1); + assert.notEqual(output.indexOf(`Bucket: ${bucketName}`), -1); + }); - filesExample.deleteFile(options, function (err) { - assert.ifError(err); - assert(console.log.calledWith('Deleted gs://%s/%s', options.bucket, options.file)); - done(); - }); + it('should delete a file', (done) => { + const output = run(`${cmd} delete ${bucketName} ${copiedFileName}`, cwd); + assert.equal(output, `File ${copiedFileName} deleted.`); + storage.bucket(bucketName).file(copiedFileName).exists((err, exists) => { + assert.ifError(err); + assert.equal(exists, false); + done(); }); }); }); diff --git a/storage/system-test/transfer.test.js b/storage/system-test/transfer.test.js index aabfd1eec2..ae1d8c081e 100644 --- a/storage/system-test/transfer.test.js +++ b/storage/system-test/transfer.test.js @@ -1,15 +1,17 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; diff --git a/storage/test/acl.test.js b/storage/test/acl.test.js index 12d2835c6f..71014b9d5e 100644 --- a/storage/test/acl.test.js +++ b/storage/test/acl.test.js @@ -1,391 +1,74 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var proxyquire = require('proxyquire').noCallThru(); -var bucketName = 'foo'; -var fileName = 'file.txt'; -var entity = 'user-bob@domain.com'; -var role = 'OWNER'; - -function getSample () { - var aclObjectMock = {}; - var fileMock = { - acl: { - add: sinon.stub().yields(null, aclObjectMock), - get: sinon.stub().yields(null, aclObjectMock), - delete: sinon.stub().yields(null, aclObjectMock) - }, - name: fileName - }; - var bucketMock = { - acl: { - add: sinon.stub().yields(null, aclObjectMock), - get: sinon.stub().yields(null, aclObjectMock), - delete: sinon.stub().yields(null, aclObjectMock), - default: { - add: sinon.stub().yields(null, aclObjectMock), - get: sinon.stub().yields(null, aclObjectMock), - delete: sinon.stub().yields(null, aclObjectMock) +const proxyquire = require(`proxyquire`).noCallThru(); + +describe(`storage:acl`, () => { + it(`should handle errors`, () => { + const bucketName = `foo`; + const fileName = `file.txt`; + const userEmail = `bob@company.com`; + const error = new Error(`error`); + const callback = sinon.spy(); + const fileMock = { + acl: { + get: sinon.stub().yields(error), + owners: { + addUser: sinon.stub().yields(error), + deleteUser: sinon.stub().yields(error) + } } - }, - file: sinon.stub().returns(fileMock), - name: bucketName - }; - var storageMock = { - bucket: sinon.stub().returns(bucketMock) - }; - var StorageMock = sinon.stub().returns(storageMock); - - return { - program: proxyquire('../acl', { - '@google-cloud/storage': StorageMock, - yargs: proxyquire('yargs', {}) - }), - mocks: { - Storage: StorageMock, - storage: storageMock, - bucket: bucketMock, - file: fileMock, - aclObject: aclObjectMock - } - }; -} - -describe('storage:acl', function () { - describe('addAccessControl', function () { - it('should add access controls to bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - entity: entity, - role: role - }; - - sample.program.addAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.add.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.add.firstCall.args.slice(0, -1), [{ - entity: entity, - role: role - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Added access controls to: gs://%s', bucketName, '']); - }); - - it('should add "default" access controls to bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - entity: entity, - role: role, - default: true - }; - - sample.program.addAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.default.add.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.default.add.firstCall.args.slice(0, -1), [{ - entity: entity, - role: role - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Added access controls to: gs://%s', bucketName, '']); - }); - - it('should add access controls to a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - entity: entity, - role: role, - file: fileName - }; - - sample.program.addAccessControl(options, callback); - - assert.equal(sample.mocks.file.acl.add.calledOnce, true); - assert.deepEqual(sample.mocks.file.acl.add.firstCall.args.slice(0, -1), [{ - entity: entity, - role: role - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Added access controls to: gs://%s/%s', bucketName, fileName]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.bucket.acl.add.yields(error); - - sample.program.addAccessControl({ - bucket: bucketName, - entity: entity, - role: role - }, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('getAccessControl', function () { - it('should get all access controls for a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName - }; - - sample.program.getAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.get.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.get.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Got access controls for: gs://%s', bucketName, '']); - }); - - it('should get all "default" access controls for a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - default: true - }; - - sample.program.getAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.default.get.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.default.get.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Got access controls for: gs://%s', bucketName, '']); - }); - - it('should get an entity\'s access controls for a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - entity: entity - }; - sample.mocks.bucket.acl.get.yields(null, sample.mocks.aclObject); - - sample.program.getAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.get.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.get.firstCall.args.slice(0, -1), [{ - entity: entity - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Got access controls for: gs://%s', bucketName, '']); - }); - - it('should get an entity\'s "default" access controls for a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - entity: entity, - default: true - }; - sample.mocks.bucket.acl.default.get.yields(null, sample.mocks.aclObject); - - sample.program.getAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.default.get.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.default.get.firstCall.args.slice(0, -1), [{ - entity: entity - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Got access controls for: gs://%s', bucketName, '']); - }); - - it('should get access controls for a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: fileName - }; - - sample.program.getAccessControl(options, callback); - - assert.equal(sample.mocks.file.acl.get.calledOnce, true); - assert.deepEqual(sample.mocks.file.acl.get.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.aclObject]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Got access controls for: gs://%s/%s', bucketName, fileName]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName - }; - sample.mocks.bucket.acl.get.yields(error); - - sample.program.getAccessControl(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('deleteAccessControl', function () { - it('should delete an entity\'s access controls from a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - entity: entity - }; - sample.mocks.bucket.acl.delete.yields(null, sample.mocks.aclObject); - - sample.program.deleteAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.delete.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.delete.firstCall.args.slice(0, -1), [{ - entity: entity - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Deleted access controls from: gs://%s', bucketName, '']); - }); - - it('should delete an entity\'s "default" access controls from a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - entity: entity, - default: true - }; - sample.mocks.bucket.acl.default.delete.yields(null, sample.mocks.aclObject); - - sample.program.deleteAccessControl(options, callback); - - assert.equal(sample.mocks.bucket.acl.default.delete.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.acl.default.delete.firstCall.args.slice(0, -1), [{ - entity: entity - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Deleted access controls from: gs://%s', bucketName, '']); - }); - - it('should delete access controls from a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: fileName, - entity: entity - }; - - sample.program.deleteAccessControl(options, callback); - - assert.equal(sample.mocks.file.acl.delete.calledOnce, true); - assert.deepEqual(sample.mocks.file.acl.delete.firstCall.args.slice(0, -1), [{ - entity: entity - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Deleted access controls from: gs://%s/%s', bucketName, fileName]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName - }; - sample.mocks.bucket.acl.delete.yields(error); - - sample.program.deleteAccessControl(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('main', function () { - it('should call addAccessControl', function () { - var program = getSample().program; - - sinon.stub(program, 'addAccessControl'); - program.main(['add', entity, role, '-b', bucketName]); - assert.equal(program.addAccessControl.calledOnce, true); - assert.deepEqual(program.addAccessControl.firstCall.args.slice(0, -1), [{ - entity: entity, - role: role, - bucket: bucketName, - default: false, - file: undefined - }]); - }); - - it('should call getAccessControl', function () { - var program = getSample().program; - - sinon.stub(program, 'getAccessControl'); - program.main(['get', entity, '-b', bucketName]); - assert.equal(program.getAccessControl.calledOnce, true); - assert.deepEqual(program.getAccessControl.firstCall.args.slice(0, -1), [{ - entity: entity, - bucket: bucketName, - default: false, - file: undefined - }]); - }); - - it('should call deleteAccessControl', function () { - var program = getSample().program; - - sinon.stub(program, 'deleteAccessControl'); - program.main(['delete', entity, '-b', bucketName]); - assert.equal(program.deleteAccessControl.calledOnce, true); - assert.deepEqual(program.deleteAccessControl.firstCall.args.slice(0, -1), [{ - entity: entity, - bucket: bucketName, - default: false, - file: undefined - }]); - }); + }; + const bucketMock = { + acl: { + get: sinon.stub().yields(error), + owners: { + addUser: sinon.stub().yields(error), + deleteUser: sinon.stub().yields(error) + }, + default: { + owners: { + addUser: sinon.stub().yields(error), + deleteUser: sinon.stub().yields(error) + } + } + }, + file: sinon.stub().returns(fileMock) + }; + const storageMock = { + bucket: sinon.stub().returns(bucketMock) + }; + const StorageMock = sinon.stub().returns(storageMock); + const program = proxyquire(`../acl`, { + '@google-cloud/storage': StorageMock + }); + + program.printBucketAcl(bucketName, callback); + program.printBucketAclForUser(bucketName, userEmail, callback); + program.addBucketOwner(bucketName, userEmail, callback); + program.removeBucketOwner(bucketName, userEmail, callback); + program.addBucketDefaultOwner(bucketName, userEmail, callback); + program.removeBucketDefaultOwner(bucketName, userEmail, callback); + program.printFileAcl(bucketName, fileName, callback); + program.printFileAclForUser(bucketName, fileName, userEmail, callback); + program.addFileOwner(bucketName, fileName, userEmail, callback); + program.removeFileOwner(bucketName, fileName, userEmail, callback); + + assert.equal(callback.callCount, 10); + assert.equal(callback.alwaysCalledWithExactly(error), true); }); }); diff --git a/storage/test/buckets.test.js b/storage/test/buckets.test.js index cfb2a2a5ce..0447aa49e3 100644 --- a/storage/test/buckets.test.js +++ b/storage/test/buckets.test.js @@ -1,163 +1,45 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var proxyquire = require('proxyquire').noCallThru(); -var bucketName = 'foo'; - -function getSample () { - var bucketsMock = [ - { - id: 'foo', - name: 'foo' - } - ]; - var bucketMock = { - create: sinon.stub().yields(null, bucketsMock[0]), - delete: sinon.stub().yields(null) - }; - var storageMock = { - getBuckets: sinon.stub().yields(null, bucketsMock, null, bucketsMock), - bucket: sinon.stub().returns(bucketMock) - }; - var StorageMock = sinon.stub().returns(storageMock); - - return { - program: proxyquire('../buckets', { - '@google-cloud/storage': StorageMock, - yargs: proxyquire('yargs', {}) - }), - mocks: { - Storage: StorageMock, - storage: storageMock, - buckets: bucketsMock, - bucket: bucketMock - } - }; -} - -describe('storage:buckets', function () { - describe('createBucket', function () { - it('should create a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.createBucket(bucketName, callback); - - assert.equal(sample.mocks.bucket.create.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.create.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.buckets[0]]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Created bucket: %s', bucketName]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.bucket.create.yields(error); - - sample.program.createBucket(bucketName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('listBuckets', function () { - it('should list buckets', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.listBuckets(callback); - - assert.equal(sample.mocks.storage.getBuckets.calledOnce, true); - assert.deepEqual(sample.mocks.storage.getBuckets.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.buckets]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d bucket(s)!', sample.mocks.buckets.length]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.storage.getBuckets.yields(error); - - sample.program.listBuckets(callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('deleteBuckets', function () { - it('should delete a bucket', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.deleteBucket(bucketName, callback); - - assert.equal(sample.mocks.bucket.delete.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.delete.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Deleted bucket: %s', bucketName]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.bucket.delete.yields(error); - - sample.program.deleteBucket(bucketName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('main', function () { - it('should call createBucket', function () { - var program = getSample().program; - - sinon.stub(program, 'createBucket'); - program.main(['create', bucketName]); - assert.equal(program.createBucket.calledOnce, true); - assert.deepEqual(program.createBucket.firstCall.args.slice(0, -1), [bucketName]); - }); - - it('should call listBuckets', function () { - var program = getSample().program; - - sinon.stub(program, 'listBuckets'); - program.main(['list']); - assert.equal(program.listBuckets.calledOnce, true); - assert.deepEqual(program.listBuckets.firstCall.args.slice(0, -1), []); - }); - - it('should call deleteBucket', function () { - var program = getSample().program; - - sinon.stub(program, 'deleteBucket'); - program.main(['delete', bucketName]); - assert.equal(program.deleteBucket.calledOnce, true); - assert.deepEqual(program.deleteBucket.firstCall.args.slice(0, -1), [bucketName]); - }); +const proxyquire = require(`proxyquire`).noCallThru(); + +describe(`storage:buckets`, () => { + it(`should handle errors`, () => { + const bucketName = `foo`; + const error = new Error(`error`); + const callback = sinon.spy(); + const bucketMock = { + delete: sinon.stub().yields(error) + }; + const storageMock = { + bucket: sinon.stub().returns(bucketMock), + getBuckets: sinon.stub().yields(error), + createBucket: sinon.stub().yields(error) + }; + const StorageMock = sinon.stub().returns(storageMock); + const program = proxyquire(`../buckets`, { + '@google-cloud/storage': StorageMock + }); + + program.createBucket(bucketName, callback); + program.deleteBucket(bucketName, callback); + program.listBuckets(callback); + + assert.equal(callback.callCount, 3); + assert.equal(callback.alwaysCalledWithExactly(error), true); }); }); diff --git a/storage/test/encryption.test.js b/storage/test/encryption.test.js index 948378dfd2..5463762475 100644 --- a/storage/test/encryption.test.js +++ b/storage/test/encryption.test.js @@ -1,215 +1,50 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var proxyquire = require('proxyquire').noCallThru(); -var bucketName = 'foo'; -var fileName = 'file.txt'; -var key = 'keyboard-cat'; - -function getSample () { - var filesMock = [ - { - id: 'foo', - name: 'foo' - } - ]; - var fileMock = { - download: sinon.stub().yields(null), - setEncryptionKey: sinon.stub() - }; - var bucketMock = { - upload: sinon.stub().yields(null, filesMock[0]), - file: sinon.stub().returns(fileMock) - }; - var storageMock = { - bucket: sinon.stub().returns(bucketMock) - }; - var StorageMock = sinon.stub().returns(storageMock); - - return { - program: proxyquire('../encryption', { - '@google-cloud/storage': StorageMock, - yargs: proxyquire('yargs', {}) - }), - mocks: { - Storage: StorageMock, - storage: storageMock, - files: filesMock, - bucket: bucketMock, - file: fileMock - } - }; -} - -describe('storage:encryption', function () { - describe('generateEncryptionKey', function () { - it('should generate an encryption key', function () { - var program = getSample().program; - - var key = program.generateEncryptionKey(); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Base 64 encoded encryption key: %s', key]); - }); - }); - - describe('uploadEncryptedFile', function () { - it('should upload a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: fileName, - destFile: fileName, - key: key - }; - - sample.program.uploadEncryptedFile(options, callback); - - assert.equal(sample.mocks.bucket.upload.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.upload.firstCall.args.slice(0, -1), [fileName, { - destination: options.destFile, - encryptionKey: new Buffer(options.key, 'base64') - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.files[0]]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Uploaded gs://%s/%s', options.bucket, options.destFile]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: fileName, - destFile: fileName, - key: key - }; - sample.mocks.bucket.upload.yields(error); - - sample.program.uploadEncryptedFile(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('downloadEncryptedFile', function () { - it('should download a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: fileName, - destFile: fileName, - key: key - }; - - sample.program.downloadEncryptedFile(options, callback); - - assert.equal(sample.mocks.file.download.calledOnce, true); - assert.deepEqual(sample.mocks.file.download.firstCall.args.slice(0, -1), [{ - destination: options.destFile - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Downloaded gs://%s/%s to %s', options.bucket, options.srcFile, options.destFile]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: fileName, - destFile: fileName, - key: key - }; - sample.mocks.file.download.yields(error); - - sample.program.downloadEncryptedFile(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('rotateEncryptionKey', function () { - it('should be implemented'); - it('should rotate an encryption key', function () { - var sample = getSample(); - var callback = sinon.stub(); - var expected = 'This is currently not available using the Cloud Client Library.'; - - sample.program.rotateEncryptionKey(callback); - - assert(callback.calledOnce, 'callback called once'); - assert.equal(callback.firstCall.args.length, 1, 'callback received 1 argument'); - assert(callback.firstCall.args[0], 'callback received error'); - assert.equal(callback.firstCall.args[0].message, expected, 'error has correct message'); - }); - }); - - describe('main', function () { - it('should call generateEncryptionKey', function () { - var program = getSample().program; - - sinon.stub(program, 'generateEncryptionKey'); - program.main(['generate-encryption-key']); - assert.equal(program.generateEncryptionKey.calledOnce, true); - assert.deepEqual(program.generateEncryptionKey.firstCall.args.slice(0, -1), []); - }); - - it('should call uploadEncryptedFile', function () { - var program = getSample().program; - - sinon.stub(program, 'uploadEncryptedFile'); - program.main(['upload', bucketName, fileName, fileName, key]); - assert.equal(program.uploadEncryptedFile.calledOnce, true); - assert.deepEqual(program.uploadEncryptedFile.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - srcFile: fileName, - destFile: fileName, - key: key - }]); - }); - - it('should call downloadEncryptedFile', function () { - var program = getSample().program; - - sinon.stub(program, 'downloadEncryptedFile'); - program.main(['download', bucketName, fileName, fileName, key]); - assert.equal(program.downloadEncryptedFile.calledOnce, true); - assert.deepEqual(program.downloadEncryptedFile.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - srcFile: fileName, - destFile: fileName, - key: key - }]); - }); - - it('should call rotateEncryptionKey', function () { - var program = getSample().program; - - sinon.stub(program, 'rotateEncryptionKey'); - program.main(['rotate', bucketName, fileName, key, key]); - assert.equal(program.rotateEncryptionKey.calledOnce, true); - assert.deepEqual(program.rotateEncryptionKey.firstCall.args.slice(0, -1), []); - }); +const proxyquire = require(`proxyquire`).noCallThru(); + +describe(`storage:encryption`, () => { + it(`should handle errors`, () => { + const bucketName = `foo`; + const fileName = `file.txt`; + const key = `keyboard-cat`; + const error = new Error(`error`); + const callback = sinon.spy(); + const fileMock = { + download: sinon.stub().yields(error), + setEncryptionKey: sinon.stub() + }; + const bucketMock = { + file: sinon.stub().returns(fileMock), + upload: sinon.stub().yields(error) + }; + const storageMock = { + bucket: sinon.stub().returns(bucketMock) + }; + const StorageMock = sinon.stub().returns(storageMock); + const program = proxyquire(`../encryption`, { + '@google-cloud/storage': StorageMock + }); + + program.uploadEncryptedFile(bucketName, fileName, fileName, key, callback); + program.downloadEncryptedFile(bucketName, fileName, fileName, key, callback); + + assert.equal(callback.callCount, 2); + assert.equal(callback.alwaysCalledWithExactly(error), true); }); }); + diff --git a/storage/test/files.test.js b/storage/test/files.test.js index bd8288ce30..b48235f9e4 100644 --- a/storage/test/files.test.js +++ b/storage/test/files.test.js @@ -1,529 +1,62 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; -var proxyquire = require('proxyquire').noCallThru(); -var bucketName = 'foo'; -var srcFileName = 'test1.txt'; -var destFileName = 'test2.txt'; -var movedFileName = 'test3.txt'; -var copiedFileName = 'test4.txt'; - -function getSample () { - var filesMock = [ - { - id: 'foo', - name: 'foo' - } - ]; - var fileMock = { - download: sinon.stub().yields(null), - getMetadata: sinon.stub().yields(null, { foo: 'bar' }), - makePublic: sinon.stub().yields(null), - delete: sinon.stub().yields(null), - move: sinon.stub().yields(null, filesMock[0]), - copy: sinon.stub().yields(null, filesMock[0]) - }; - var bucketMock = { - getFiles: sinon.stub().yields(null, filesMock), - file: sinon.stub().returns(fileMock), - upload: sinon.stub().yields(null, filesMock[0]) - }; - var storageMock = { - bucket: sinon.stub().returns(bucketMock) - }; - var StorageMock = sinon.stub().returns(storageMock); - - return { - program: proxyquire('../files', { - '@google-cloud/storage': StorageMock, - yargs: proxyquire('yargs', {}) - }), - mocks: { - Storage: StorageMock, - storage: storageMock, - files: filesMock, - file: fileMock, - bucket: bucketMock - } - }; -} - -describe('storage:files', function () { - describe('list', function () { - it('should list files', function () { - var sample = getSample(); - var callback = sinon.stub(); - - sample.program.listFiles(bucketName, callback); - - assert.equal(sample.mocks.bucket.getFiles.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.getFiles.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.files]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d file(s)!', sample.mocks.files.length]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - sample.mocks.bucket.getFiles.yields(error); - - sample.program.listFiles(bucketName, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('listFilesByPrefix', function () { - it('should list files with prefix', function () { - var sample = getSample(); - var callback = sinon.stub(); - var prefix = '/a'; - var options = { - bucket: bucketName, - prefix: prefix - }; - - sample.program.listFilesByPrefix(options, callback); - - assert.equal(sample.mocks.bucket.getFiles.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.getFiles.firstCall.args.slice(0, -1), [{ - prefix: prefix - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.files]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d file(s)!', sample.mocks.files.length]); - }); - - it('should list files with prefix and delimiter', function () { - var sample = getSample(); - var callback = sinon.stub(); - var prefix = '/a'; - var delimiter = '-'; - var options = { - bucket: bucketName, - prefix: prefix, - delimiter: delimiter - }; - - sample.program.listFilesByPrefix(options, callback); - - assert.equal(sample.mocks.bucket.getFiles.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.getFiles.firstCall.args.slice(0, -1), [{ - prefix: prefix, - delimiter: delimiter - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.files]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Found %d file(s)!', sample.mocks.files.length]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var prefix = '/a'; - var options = { - bucket: bucketName, - prefix: prefix - }; - sample.mocks.bucket.getFiles.yields(error); - - sample.program.listFilesByPrefix(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('uploadFile', function () { - it('should upload a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: srcFileName - }; - - sample.program.uploadFile(options, callback); - - assert.equal(sample.mocks.bucket.upload.calledOnce, true); - assert.deepEqual(sample.mocks.bucket.upload.firstCall.args.slice(0, -1), [srcFileName]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.files[0]]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Uploaded gs://%s/%s', options.bucket, options.srcFile]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: srcFileName - }; - sample.mocks.bucket.upload.yields(error); - - sample.program.uploadFile(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('downloadFile', function () { - it('should download a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: srcFileName, - destFile: destFileName - }; - - sample.program.downloadFile(options, callback); - - assert.equal(sample.mocks.file.download.calledOnce, true); - assert.deepEqual(sample.mocks.file.download.firstCall.args.slice(0, -1), [{ - destination: options.destFile - }]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Downloaded gs://%s/%s to %s', options.bucket, options.srcFile, options.destFile]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: srcFileName, - destFile: destFileName - }; - sample.mocks.file.download.yields(error); - - sample.program.downloadFile(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('deleteFile', function () { - it('should delete a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: srcFileName - }; - - sample.program.deleteFile(options, callback); - - assert.equal(sample.mocks.file.delete.calledOnce, true); - assert.deepEqual(sample.mocks.file.delete.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Deleted gs://%s/%s', options.bucket, options.file]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: srcFileName - }; - sample.mocks.file.delete.yields(error); - - sample.program.deleteFile(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('getMetadata', function () { - it('should get metadata for a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: srcFileName - }; - - sample.program.getMetadata(options, callback); - - assert.equal(sample.mocks.file.getMetadata.calledOnce, true); - assert.deepEqual(sample.mocks.file.getMetadata.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, { foo: 'bar' }]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Got metadata for gs://%s/%s', options.bucket, options.file]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: srcFileName - }; - sample.mocks.file.getMetadata.yields(error); - - sample.program.getMetadata(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('makePublic', function () { - it('should make a file public', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: srcFileName - }; - - sample.program.makePublic(options, callback); - - assert.equal(sample.mocks.file.makePublic.calledOnce, true); - assert.deepEqual(sample.mocks.file.makePublic.firstCall.args.slice(0, -1), []); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Made gs://%s/%s public!', options.bucket, options.file]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - file: srcFileName - }; - sample.mocks.file.makePublic.yields(error); - - sample.program.makePublic(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('moveFile', function () { - it('should rename a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: srcFileName, - destFile: movedFileName - }; - - sample.program.moveFile(options, callback); - - assert.equal(sample.mocks.file.move.calledOnce, true); - assert.deepEqual(sample.mocks.file.move.firstCall.args.slice(0, -1), [options.destFile]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.files[0]]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Renamed gs://%s/%s to gs://%s/%s', options.bucket, options.srcFile, options.bucket, options.destFile]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - bucket: bucketName, - srcFile: srcFileName, - destFile: movedFileName - }; - sample.mocks.file.move.yields(error); - - sample.program.moveFile(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('copyFile', function () { - it('should copy a file', function () { - var sample = getSample(); - var callback = sinon.stub(); - var options = { - srcBucket: bucketName, - srcFile: srcFileName, - destFile: copiedFileName, - destBucket: bucketName - }; - - sample.program.copyFile(options, callback); - - assert.equal(sample.mocks.file.copy.calledOnce, true); - assert.deepEqual(sample.mocks.file.copy.firstCall.args.slice(0, -1), [sample.mocks.storage.bucket(options.destBucket).file(options.destFile)]); - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [null, sample.mocks.files[0]]); - assert.equal(console.log.calledOnce, true); - assert.deepEqual(console.log.firstCall.args, ['Copied gs://%s/%s to gs://%s/%s', options.srcBucket, options.srcFile, options.destBucket, options.destFile]); - }); - - it('should handle error', function () { - var error = new Error('error'); - var sample = getSample(); - var callback = sinon.stub(); - var options = { - srcBucket: bucketName, - srcFile: srcFileName, - destFile: copiedFileName, - destBucket: bucketName - }; - sample.mocks.file.copy.yields(error); - - sample.program.copyFile(options, callback); - - assert.equal(callback.calledOnce, true); - assert.deepEqual(callback.firstCall.args, [error]); - }); - }); - - describe('main', function () { - it('should call listFiles', function () { - var program = getSample().program; - - sinon.stub(program, 'listFiles'); - program.main(['list', bucketName]); - assert.equal(program.listFiles.calledOnce, true); - assert.deepEqual(program.listFiles.firstCall.args.slice(0, -1), [bucketName]); - }); - - it('should call listFilesByPrefix', function () { - var program = getSample().program; - - sinon.stub(program, 'listFilesByPrefix'); - program.main(['list', bucketName, '-p', 'public/']); - assert.equal(program.listFilesByPrefix.calledOnce, true); - assert.deepEqual(program.listFilesByPrefix.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - prefix: 'public/', - delimiter: undefined - }]); - }); - - it('should call uploadFile', function () { - var program = getSample().program; - - sinon.stub(program, 'uploadFile'); - program.main(['upload', bucketName, srcFileName]); - assert.equal(program.uploadFile.calledOnce, true); - assert.deepEqual(program.uploadFile.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - srcFile: srcFileName - }]); - }); - - it('should call downloadFile', function () { - var program = getSample().program; - - sinon.stub(program, 'downloadFile'); - program.main(['download', bucketName, srcFileName, destFileName]); - assert.equal(program.downloadFile.calledOnce, true); - assert.deepEqual(program.downloadFile.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - srcFile: srcFileName, - destFile: destFileName - }]); - }); - - it('should call deleteFile', function () { - var program = getSample().program; - - sinon.stub(program, 'deleteFile'); - program.main(['delete', bucketName, srcFileName]); - assert.equal(program.deleteFile.calledOnce, true); - assert.deepEqual(program.deleteFile.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - file: srcFileName - }]); - }); - - it('should call getMetadata', function () { - var program = getSample().program; - - sinon.stub(program, 'getMetadata'); - program.main(['getMetadata', bucketName, srcFileName]); - assert.equal(program.getMetadata.calledOnce, true); - assert.deepEqual(program.getMetadata.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - file: srcFileName - }]); - }); - - it('should call makePublic', function () { - var program = getSample().program; - - sinon.stub(program, 'makePublic'); - program.main(['makePublic', bucketName, srcFileName]); - assert.equal(program.makePublic.calledOnce, true); - assert.deepEqual(program.makePublic.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - file: srcFileName - }]); - }); - - it('should call moveFile', function () { - var program = getSample().program; - - sinon.stub(program, 'moveFile'); - program.main(['move', bucketName, srcFileName, movedFileName]); - assert.equal(program.moveFile.calledOnce, true); - assert.deepEqual(program.moveFile.firstCall.args.slice(0, -1), [{ - bucket: bucketName, - srcFile: srcFileName, - destFile: movedFileName - }]); - }); - - it('should call copyFile', function () { - var program = getSample().program; - - sinon.stub(program, 'copyFile'); - program.main(['copy', bucketName, srcFileName, bucketName, copiedFileName]); - assert.equal(program.copyFile.calledOnce, true); - assert.deepEqual(program.copyFile.firstCall.args.slice(0, -1), [{ - srcBucket: bucketName, - srcFile: srcFileName, - destBucket: bucketName, - destFile: copiedFileName - }]); - }); +const proxyquire = require(`proxyquire`).noCallThru(); + +describe(`storage:files`, () => { + it(`should handle errors`, () => { + const bucketName = `foo`; + const fileName = `file.txt`; + const error = new Error(`error`); + const callback = sinon.spy(); + const fileMock = { + copy: sinon.stub().yields(error), + delete: sinon.stub().yields(error), + download: sinon.stub().yields(error), + getMetadata: sinon.stub().yields(error), + getSignedUrl: sinon.stub().yields(error), + makePublic: sinon.stub().yields(error), + move: sinon.stub().yields(error) + }; + const bucketMock = { + file: sinon.stub().returns(fileMock), + getFiles: sinon.stub().yields(error), + upload: sinon.stub().yields(error) + }; + const storageMock = { + bucket: sinon.stub().returns(bucketMock) + }; + const StorageMock = sinon.stub().returns(storageMock); + const program = proxyquire(`../files`, { + '@google-cloud/storage': StorageMock + }); + + program.listFiles(bucketName, callback); + program.listFilesByPrefix(bucketName, `public/`, undefined, callback); + program.uploadFile(bucketName, fileName, callback); + program.downloadFile(bucketName, fileName, fileName, callback); + program.deleteFile(bucketName, fileName, callback); + program.getMetadata(bucketName, fileName, callback); + program.generateSignedUrl(bucketName, fileName, callback); + program.makePublic(bucketName, fileName, callback); + program.moveFile(bucketName, fileName, fileName, callback); + program.copyFile(bucketName, fileName, bucketName, fileName, callback); + + assert.equal(callback.callCount, 10); + assert.equal(callback.alwaysCalledWithExactly(error), true); }); }); diff --git a/storage/test/transfer.test.js b/storage/test/transfer.test.js index 4870a8741a..baef195cd2 100644 --- a/storage/test/transfer.test.js +++ b/storage/test/transfer.test.js @@ -1,15 +1,17 @@ -// Copyright 2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; diff --git a/storage/transfer.js b/storage/transfer.js index dbce782e35..1fcc80aa09 100644 --- a/storage/transfer.js +++ b/storage/transfer.js @@ -1,15 +1,17 @@ -// Copyright 2015-2016, Google, Inc. -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/** + * Copyright 2016, Google, Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ 'use strict'; diff --git a/utils/index.js b/utils/index.js index 05bd0affde..f66599a4ae 100644 --- a/utils/index.js +++ b/utils/index.js @@ -58,3 +58,9 @@ exports.makeHandler = function (print, field) { } }; }; + +exports.noop = (err) => { + if (err) { + throw err; + } +};