diff --git a/pubsub/system-test/subscriptions.test.js b/pubsub/system-test/subscriptions.test.js index 7f601b2b7c..7f6711221b 100644 --- a/pubsub/system-test/subscriptions.test.js +++ b/pubsub/system-test/subscriptions.test.js @@ -39,7 +39,8 @@ describe('pubsub:subscriptions', function () { assert.ifError(err); assert.equal(subscription.name, name); assert(console.log.calledWith('Created subscription %s to topic %s', subscriptionName, topicName)); - done(); + // The next test sometimes fails, so, slow this test down + setTimeout(done, 2000); }); }); }); diff --git a/storage/README.md b/storage/README.md index 5116817041..c957e48a11 100644 --- a/storage/README.md +++ b/storage/README.md @@ -33,13 +33,19 @@ View the [documentation][buckets_docs] or the [source code][buckets_code]. __Usage:__ `node buckets --help` ``` -Usage: node buckets [COMMAND] [ARGS...] +Usage: node buckets COMMAND [ARGS...] Commands: - create [BUCKET_NAME] + create BUCKET_NAME list - delete [BUCKET_NAME] + delete BUCKET_NAME + +Examples: + + node buckets create my-bucket + node buckets list + node buckets delete my-bucket ``` [buckets_docs]: https://cloud.google.com/storage/docs @@ -52,20 +58,60 @@ View the [documentation][files_docs] or the [source code][files_code]. __Usage:__ `node files --help` ``` -Usage: node files [COMMAND] [ARGS...] +Usage: node files COMMAND [ARGS...] Commands: - list [BUCKET_NAME] - listByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER] - upload [BUCKET_NAME] [FILE_NAME] - download [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME] - delete [BUCKET_NAME] [FILE_NAME] - getMetadata [BUCKET_NAME] [FILE_NAME] - makePublic [BUCKET_NAME] [FILE_NAME] - move [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME] - copy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME] + list BUCKET_NAME + listByPrefix BUCKET_NAME PREFIX [DELIMITER] + upload BUCKET_NAME FILE_NAME + download BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME + delete BUCKET_NAME FILE_NAME + getMetadata BUCKET_NAME FILE_NAME + makePublic BUCKET_NAME FILE_NAME + move BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME + copy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME + +Examples: + + list my-bucket + listByPrefix my-bucket /some-folder + listByPrefix my-bucket /some-folder - + upload my-bucket ./file.txt + download my-bucket file.txt ./file.txt + delete my-bucket file.txt + getMetadata my-bucket file.txt + makePublic my-bucket file.txt + move my-bucket file.txt file2.txt + copy my-bucket file.txt my-other-bucket file.txt ``` [files_docs]: https://cloud.google.com/storage/docs [files_code]: files.js + +### Encryption + +View the [documentation][encryption_docs] or the [source code][encryption_code]. + +__Usage:__ `node encryption --help` + +``` +Usage: node encryption COMMAND [ARGS...] + +Commands: + + generate-encryption-key + upload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY + download BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY + rotate BUCKET_NAME FILE_NAME OLD_KEY NEW_KEY + +Examples: + + node encryption generate-encryption-key + node encryption upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= + node encryption download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q= + node encryption rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q= +``` + +[encryption_docs]: https://cloud.google.com/storage/docs +[encryption_code]: encryption.js diff --git a/storage/buckets.js b/storage/buckets.js index 4d809e9fae..866e5dfd40 100644 --- a/storage/buckets.js +++ b/storage/buckets.js @@ -21,7 +21,7 @@ // https://googlecloudplatform.github.io/gcloud-node/#/docs/guides/authentication var gcloud = require('gcloud'); -// Get a reference to the storage component +// Instantiate a storage client var storage = gcloud.storage(); // [END setup] @@ -93,11 +93,15 @@ function deleteBucket (name, callback) { // [START usage] function printUsage () { - console.log('Usage: node buckets [COMMAND] [ARGS...]'); + console.log('Usage: node buckets COMMAND [ARGS...]'); console.log('\nCommands:\n'); - console.log('\tcreate [BUCKET_NAME]'); + console.log('\tcreate BUCKET_NAME'); console.log('\tlist'); - console.log('\tdelete [BUCKET_NAME]'); + console.log('\tdelete BUCKET_NAME'); + console.log('\nExamples:\n'); + console.log('\tnode buckets create my-bucket'); + console.log('\tnode buckets list'); + console.log('\tnode buckets delete my-bucket'); } // [END usage] diff --git a/storage/encryption.js b/storage/encryption.js new file mode 100644 index 0000000000..64ba417fee --- /dev/null +++ b/storage/encryption.js @@ -0,0 +1,193 @@ +// 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'; + +// [START all] +// [START setup] +// By default, gcloud 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/guides/authentication +var gcloud = require('gcloud'); + +// Instantiate a storage client +var storage = gcloud.storage(); + +var crypto = require('crypto'); +// [END setup] + +// [START generate_encryption_key] +/** + * Generates a 256 bit (32 byte) AES encryption key and prints the base64 + * representation. + * + * This is included for demonstration purposes. You should generate your own + * key. Please remember that encryption keys should be handled with a + * comprehensive security policy. + * + * @returns {string} The encryption key. + */ +function generateEncryptionKey () { + var buffer = crypto.randomBytes(32); + var encodedKey = buffer.toString('base64'); + + console.log('Base 64 encoded encryption key: %s', encodedKey); + + return encodedKey; +} +// [END 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 {string} bucketName The bucket where the file will be uploaded. + * @param {string} srcFileName The local file to be uploaded. + * @param {string} destFileName The name of the destination file. + * @param {string} key The encryption key. + * @param {function} callback The callback function. + */ +function uploadEncryptedFile (bucketName, srcFileName, destFileName, key, callback) { + if (!bucketName) { + return callback(new Error('"bucketName" is required!')); + } else if (!srcFileName) { + return callback(new Error('"srcFileName" is required!')); + } else if (!destFileName) { + return callback(new Error('"destFileName" is required!')); + } else if (!key) { + return callback(new Error('"key" is required!')); + } + + var bucket = storage.bucket(bucketName); + var options = { + destination: destFileName, + encryptionKey: new Buffer(key, 'base64') + }; + + bucket.upload(srcFileName, options, function (err, file) { + if (err) { + return callback(err); + } + + console.log('Uploaded encrypted file: %s', destFileName); + return callback(null, file); + }); +} +// [END 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 {string} bucketName The bucket from which the file will be downloaded. + * @param {string} srcFileName The name of the file to be downloaded. + * @param {string} destFileName The local path to which to save the file. + * @param {string} key The encryption key. + * @param {function} key The callback function. + */ +function downloadEncryptedFile (bucketName, srcFileName, destFileName, key, callback) { + if (!bucketName) { + return callback(new Error('"bucketName" is required!')); + } else if (!srcFileName) { + return callback(new Error('"srcFileName" is required!')); + } else if (!destFileName) { + return callback(new Error('"destFileName" is required!')); + } else if (!key) { + return callback(new Error('"key" is required!')); + } + + var bucket = storage.bucket(bucketName); + var file = bucket.file(srcFileName); + var options = { + destination: destFileName + }; + + file.setEncryptionKey(new Buffer(key, 'base64')); + + file.download(options, function (err) { + if (err) { + return callback(err); + } + + console.log('Downloaded encrypted file: %s', destFileName); + return callback(null); + }); +} +// [END download_encrypted_file] + +// [START rotate_encryption_key] +/** + * Performs a key rotation by re-writing an encrypted blob with a new encryption + * key. + * + * @param {function} key The callback function. + */ +function rotateEncryptionKey (callback) { + callback(new Error('This is currently not available using the Cloud Client Library.')); +} +// [END rotate_encryption_key] + +// [START usage] +function printUsage () { + console.log('Usage: node encryption COMMAND [ARGS...]'); + console.log('\nCommands:\n'); + console.log('\tgenerate-encryption-key'); + console.log('\tupload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY'); + console.log('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY'); + console.log('\trotate BUCKET_NAME FILE_NAME OLD_KEY NEW_KEY'); + console.log('\nExamples:\n'); + console.log('\tnode encryption generate-encryption-key'); + console.log('\tnode encryption upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q='); + console.log('\tnode encryption download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q='); + console.log('\tnode encryption rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q='); +} +// [END usage] + +// The command-line program +var program = { + generateEncryptionKey: generateEncryptionKey, + uploadEncryptedFile: uploadEncryptedFile, + downloadEncryptedFile: downloadEncryptedFile, + rotateEncryptionKey: rotateEncryptionKey, + printUsage: printUsage, + + // Executed when this program is run from the command-line + main: function (args, cb) { + var command = args.shift(); + if (command === 'generate-encryption-key') { + this.generateEncryptionKey(); + } else if (command === 'upload') { + this.uploadEncryptedFile(args[0], args[1], args[2], args[3], cb); + } else if (command === 'download') { + this.downloadEncryptedFile(args[0], args[1], args[2], args[3], cb); + } else if (command === 'rotate') { + this.rotateEncryptionKey(cb); + } else { + this.printUsage(); + } + } +}; + +if (module === require.main) { + program.main(process.argv.slice(2), console.log); +} +// [END all] + +module.exports = program; diff --git a/storage/files.js b/storage/files.js index c248c06eef..7918996222 100644 --- a/storage/files.js +++ b/storage/files.js @@ -21,7 +21,7 @@ // https://googlecloudplatform.github.io/gcloud-node/#/docs/guides/authentication var gcloud = require('gcloud'); -// Get a reference to the storage component +// Instantiate a storage client var storage = gcloud.storage(); // [END setup] @@ -324,17 +324,28 @@ function copyFile (name, srcFileName, destBucketName, destFileName, callback) { // [START usage] function printUsage () { - console.log('Usage: node files [COMMAND] [ARGS...]'); + console.log('Usage: node files COMMAND [ARGS...]'); console.log('\nCommands:\n'); - console.log('\tlist [BUCKET_NAME]'); - console.log('\tlistByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER]'); - console.log('\tupload [BUCKET_NAME] [FILE_NAME]'); - console.log('\tdownload [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]'); - console.log('\tdelete [BUCKET_NAME] [FILE_NAME]'); - console.log('\tgetMetadata [BUCKET_NAME] [FILE_NAME]'); - console.log('\tmakePublic [BUCKET_NAME] [FILE_NAME]'); - console.log('\tmove [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]'); - console.log('\tcopy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME]'); + console.log('\tlist BUCKET_NAME'); + console.log('\tlistByPrefix BUCKET_NAME PREFIX [DELIMITER]'); + console.log('\tupload BUCKET_NAME FILE_NAME'); + console.log('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME'); + console.log('\tdelete BUCKET_NAME FILE_NAME'); + console.log('\tgetMetadata BUCKET_NAME FILE_NAME'); + console.log('\tmakePublic BUCKET_NAME FILE_NAME'); + console.log('\tmove BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME'); + console.log('\tcopy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME'); + console.log('\nExamples:\n'); + console.log('\tlist my-bucket'); + console.log('\tlistByPrefix my-bucket /some-folder'); + console.log('\tlistByPrefix my-bucket /some-folder -'); + console.log('\tupload my-bucket ./file.txt'); + console.log('\tdownload my-bucket file.txt ./file.txt'); + console.log('\tdelete my-bucket file.txt'); + console.log('\tgetMetadata my-bucket file.txt'); + console.log('\tmakePublic my-bucket file.txt'); + console.log('\tmove my-bucket file.txt file2.txt'); + console.log('\tcopy my-bucket file.txt my-other-bucket file.txt'); } // [END usage] diff --git a/storage/system-test/encryption.test.js b/storage/system-test/encryption.test.js new file mode 100644 index 0000000000..33d5dad4b0 --- /dev/null +++ b/storage/system-test/encryption.test.js @@ -0,0 +1,79 @@ +// 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'; + +var fs = require('fs'); +var path = require('path'); +var gcloud = require('gcloud'); +var uuid = require('node-uuid'); +var storage = gcloud.storage(); +var program = require('../encryption'); + +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'); + +describe('storage:encryption', function () { + var key; + + before(function (done) { + // Create an encryption key to use throughout the test + key = program.generateEncryptionKey(); + // Create a test bucket + storage.createBucket(bucketName, done); + }); + + after(function (done) { + try { + // Delete the downloaded file + fs.unlinkSync(downloadFilePath); + } catch (err) { + console.log(err); + } + // Delete any files that were uploaded + storage.bucket(bucketName).deleteFiles({ force: true }, function (err) { + if (err) { + return done(err); + } + // Delete the test bucket + storage.bucket(bucketName).delete(done); + }); + }); + + describe('uploadEncryptedFile', function () { + it('should upload a file', function (done) { + program.uploadEncryptedFile(bucketName, filePath, fileName, key, function (err, file) { + assert.ifError(err); + assert(file); + assert.equal(file.name, fileName); + assert(console.log.calledWith('Uploaded encrypted file: %s', fileName)); + done(); + }); + }); + }); + + describe('downloadEncryptedFile', function () { + it('should download a file', function (done) { + program.downloadEncryptedFile(bucketName, fileName, downloadFilePath, key, function (err) { + assert.ifError(err); + assert.doesNotThrow(function () { + fs.statSync(downloadFilePath); + }); + assert(console.log.calledWith('Downloaded encrypted file: %s', downloadFilePath)); + done(); + }); + }); + }); +}); diff --git a/storage/test/buckets.test.js b/storage/test/buckets.test.js index f80b60fa70..a7116913f1 100644 --- a/storage/test/buckets.test.js +++ b/storage/test/buckets.test.js @@ -135,11 +135,15 @@ describe('storage:buckets', function () { bucketsSample.sample.printUsage(); - assert(console.log.calledWith('Usage: node buckets [COMMAND] [ARGS...]')); + assert(console.log.calledWith('Usage: node buckets COMMAND [ARGS...]')); assert(console.log.calledWith('\nCommands:\n')); - assert(console.log.calledWith('\tcreate [BUCKET_NAME]')); + assert(console.log.calledWith('\tcreate BUCKET_NAME')); assert(console.log.calledWith('\tlist')); - assert(console.log.calledWith('\tdelete [BUCKET_NAME]')); + assert(console.log.calledWith('\tdelete BUCKET_NAME')); + assert(console.log.calledWith('\nExamples:\n')); + assert(console.log.calledWith('\tnode buckets create my-bucket')); + assert(console.log.calledWith('\tnode buckets list')); + assert(console.log.calledWith('\tnode buckets delete my-bucket')); }); }); describe('main', function () { diff --git a/storage/test/encryption.test.js b/storage/test/encryption.test.js new file mode 100644 index 0000000000..6834082014 --- /dev/null +++ b/storage/test/encryption.test.js @@ -0,0 +1,240 @@ +// 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 filesMock = [ + { + id: 'foo', + name: 'foo' + } + ]; + var fileMock = { + download: sinon.stub().callsArgWith(1, null), + setEncryptionKey: sinon.stub() + }; + var bucketMock = { + upload: sinon.stub().callsArgWith(2, null, filesMock[0]), + file: sinon.stub().returns(fileMock) + }; + var storageMock = { + bucket: sinon.stub().returns(bucketMock) + }; + var gcloudMock = { + storage: sinon.stub().returns(storageMock) + }; + return { + program: proxyquire('../encryption', { + gcloud: gcloudMock + }), + mocks: { + gcloud: gcloudMock, + 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(console.log.calledWith('Base 64 encoded encryption key: %s', key)); + }); + }); + + describe('uploadEncryptedFile', function () { + var fileName = 'test.txt'; + it('should upload a file', function () { + var sample = getSample(); + + sample.program.uploadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) { + assert.ifError(err); + assert.strictEqual(file, sample.mocks.files[0]); + assert(console.log.calledWith('Uploaded encrypted file: %s', fileName)); + }); + }); + it('should require bucket', function () { + var sample = getSample(); + + sample.program.uploadEncryptedFile(undefined, undefined, undefined, undefined, function (err, file) { + assert(err); + assert(err.message = '"bucket" is required!'); + assert.equal(file, undefined); + }); + }); + it('should require srcFileName', function () { + var sample = getSample(); + + sample.program.uploadEncryptedFile(bucketName, undefined, undefined, undefined, function (err, file) { + assert(err); + assert(err.message = '"srcFileName" is required!'); + assert.equal(file, undefined); + }); + }); + it('should require destFileName', function () { + var sample = getSample(); + + sample.program.uploadEncryptedFile(bucketName, fileName, undefined, undefined, function (err, file) { + assert(err); + assert(err.message = '"destFileName" is required!'); + assert.equal(file, undefined); + }); + }); + it('should require key', function () { + var sample = getSample(); + + sample.program.uploadEncryptedFile(bucketName, fileName, fileName, undefined, function (err, file) { + assert(err); + assert(err.message = '"key" is required!'); + assert.equal(file, undefined); + }); + }); + it('should handle error', function () { + var error = 'error'; + var sample = getSample(); + sample.mocks.bucket.upload = sinon.stub().callsArgWith(2, new Error(error)); + + sample.program.uploadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) { + assert(err); + assert.equal(err.message, error); + assert.equal(file, undefined); + }); + }); + }); + + describe('downloadEncryptedFile', function () { + var fileName = 'test.txt'; + it('should download a file', function () { + var sample = getSample(); + + sample.program.downloadEncryptedFile(bucketName, fileName, fileName, 'key', function (err) { + assert.ifError(err); + assert(console.log.calledWith('Downloaded encrypted file: %s', fileName)); + }); + }); + it('should require bucket', function () { + var sample = getSample(); + + sample.program.downloadEncryptedFile(undefined, undefined, undefined, undefined, function (err, file) { + assert(err); + assert(err.message = '"bucket" is required!'); + assert.equal(file, undefined); + }); + }); + it('should require srcFileName', function () { + var sample = getSample(); + + sample.program.downloadEncryptedFile(bucketName, undefined, undefined, undefined, function (err, file) { + assert(err); + assert(err.message = '"srcFileName" is required!'); + assert.equal(file, undefined); + }); + }); + it('should require destFileName', function () { + var sample = getSample(); + + sample.program.downloadEncryptedFile(bucketName, fileName, undefined, undefined, function (err, file) { + assert(err); + assert(err.message = '"destFileName" is required!'); + assert.equal(file, undefined); + }); + }); + it('should require key', function () { + var sample = getSample(); + + sample.program.downloadEncryptedFile(bucketName, fileName, fileName, undefined, function (err, file) { + assert(err); + assert(err.message = '"key" is required!'); + assert.equal(file, undefined); + }); + }); + it('should handle error', function () { + var error = 'error'; + var sample = getSample(); + sample.mocks.file.download = sinon.stub().callsArgWith(1, new Error(error)); + + sample.program.downloadEncryptedFile(bucketName, fileName, fileName, 'key', function (err, file) { + assert(err); + assert.equal(err.message, error); + assert.equal(file, undefined); + }); + }); + }); + + describe('rotateEncryptionKey', function () { + it('should be implemented'); + it('should rotate an encryption key', function () { + var sample = getSample(); + + sample.program.rotateEncryptionKey(function (err) { + assert(err); + assert.equal(err.message, 'This is currently not available using the Cloud Client Library.'); + }); + }); + }); + + describe('printUsage', function () { + it('should print usage', function () { + var program = getSample().program; + + program.printUsage(); + + assert(console.log.calledWith('Usage: node encryption COMMAND [ARGS...]')); + assert(console.log.calledWith('\nCommands:\n')); + assert(console.log.calledWith('\tgenerate-encryption-key')); + assert(console.log.calledWith('\tupload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY')); + assert(console.log.calledWith('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME KEY')); + assert(console.log.calledWith('\trotate BUCKET_NAME FILE_NAME OLD_KEY NEW_KEY')); + assert(console.log.calledWith('\nExamples:\n')); + assert(console.log.calledWith('\tnode encryption generate-encryption-key')); + assert(console.log.calledWith('\tnode encryption upload my-bucket resources/test.txt file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q=')); + assert(console.log.calledWith('\tnode encryption download my-bucket file_encrypted.txt ./file.txt QxhqaZEqBGVTW55HhQw9Q=')); + assert(console.log.calledWith('\tnode encryption rotate my-bucket file_encrypted.txt QxhqaZEqBGVTW55HhQw9Q= SxafpsdfSDFS89sds9Q=')); + }); + }); + + describe('main', function () { + it('should call the right commands', function () { + var program = getSample().program; + + sinon.stub(program, 'generateEncryptionKey'); + program.main(['generate-encryption-key']); + assert(program.generateEncryptionKey.calledOnce); + + sinon.stub(program, 'uploadEncryptedFile'); + program.main(['upload']); + assert(program.uploadEncryptedFile.calledOnce); + + sinon.stub(program, 'downloadEncryptedFile'); + program.main(['download']); + assert(program.downloadEncryptedFile.calledOnce); + + sinon.stub(program, 'rotateEncryptionKey'); + program.main(['rotate']); + assert(program.rotateEncryptionKey.calledOnce); + + sinon.stub(program, 'printUsage'); + program.main(['--help']); + assert(program.printUsage.calledOnce); + }); + }); +}); diff --git a/storage/test/files.test.js b/storage/test/files.test.js index ba21df7125..8e2b5fcd9c 100644 --- a/storage/test/files.test.js +++ b/storage/test/files.test.js @@ -421,17 +421,17 @@ describe('storage:files', function () { filesSample.sample.printUsage(); - assert(console.log.calledWith('Usage: node files [COMMAND] [ARGS...]')); + assert(console.log.calledWith('Usage: node files COMMAND [ARGS...]')); assert(console.log.calledWith('\nCommands:\n')); - assert(console.log.calledWith('\tlist [BUCKET_NAME]')); - assert(console.log.calledWith('\tlistByPrefix [BUCKET_NAME] [PREFIX] [DELIMITER]')); - assert(console.log.calledWith('\tupload [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tdownload [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]')); - assert(console.log.calledWith('\tdelete [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tgetMetadata [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tmakePublic [BUCKET_NAME] [FILE_NAME]')); - assert(console.log.calledWith('\tmove [BUCKET_NAME] [SRC_FILE_NAME] [DEST_FILE_NAME]')); - assert(console.log.calledWith('\tcopy [BUCKET_NAME] [SRC_FILE_NAME] [DEST_BUCKET_NAME] [DEST_FILE_NAME]')); + assert(console.log.calledWith('\tlist BUCKET_NAME')); + assert(console.log.calledWith('\tlistByPrefix BUCKET_NAME PREFIX [DELIMITER]')); + assert(console.log.calledWith('\tupload BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tdownload BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME')); + assert(console.log.calledWith('\tdelete BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tgetMetadata BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tmakePublic BUCKET_NAME FILE_NAME')); + assert(console.log.calledWith('\tmove BUCKET_NAME SRC_FILE_NAME DEST_FILE_NAME')); + assert(console.log.calledWith('\tcopy BUCKET_NAME SRC_FILE_NAME DEST_BUCKET_NAME DEST_FILE_NAME')); }); }); describe('main', function () {