diff --git a/storage/README.md b/storage/README.md index 42cfff1f05..726c8d74b9 100644 --- a/storage/README.md +++ b/storage/README.md @@ -11,7 +11,7 @@ amount of data at any time. * [Setup](#setup) * [Samples](#samples) - * [Authentication](#authentication) + * [Buckets](#buckets) ## Setup @@ -25,13 +25,33 @@ amount of data at any time. ## Samples -### Authentication +### Buckets -View the [documentation][authentication_docs] or the [source code][authentication_code]. +View the [documentation][buckets_docs] or the [source code][buckets_code]. -__Run the sample:__ +__Usage:__ - node authSample +``` +Usage: node buckets [COMMAND] [ARGS...] -[authentication_docs]: https://cloud.google.com/storage/docs/authentication#acd-examples -[authentication_code]: authSample.js +Commands: + + create [BUCKET_NAME] + list + delete [BUCKET_NAME] +``` + +__Create a bucket:__ + + node buckets create [BUCKET_NAME] + +__List buckets:__ + + node buckets list + +__Delete a bucket:__ + + node buckets delete [BUCKET_NAME] + +[buckets_docs]: https://cloud.google.com/storage/docs/json_api/v1/json-api-nodejs-samples +[buckets_code]: buckets.js diff --git a/storage/authSample.js b/storage/authSample.js deleted file mode 100644 index 2283b05f04..0000000000 --- a/storage/authSample.js +++ /dev/null @@ -1,83 +0,0 @@ -// 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. - -/** - * @fileoverview Sample code that grabs default credentials from the - * environment, then uses it to make an api call. - */ -'use strict'; - -var google = require('googleapis'); - -/** - * Callback for remote requests. - * - * @callback requestCallback - * @param {Object} err - if there's an error with the request, this is pass - * through to the callback. - * @param {Object} response - the response for the request. - */ - -/** - * Fetches a list of the buckets under the given project id. - * - * @param {String} projectId - The project id that owns the buckets. - * @param {requestCallback} cb - A function to be called when the server - * responds with the list of buckets. - */ -// [START list_buckets] -function listBucketsExample (projectId, callback) { - google.auth.getApplicationDefault(function (err, authClient) { - if (err) { - return callback(err); - } - - // Depending on the environment that provides the default credentials - // (e.g. Compute Engine, App Engine), the credentials retrieved may require - // you to specify the scopes you need explicitly. - // Check for this case, and inject the Cloud Storage scope if required. - if (authClient.createScopedRequired && - authClient.createScopedRequired()) { - authClient = authClient.createScoped( - ['https://www.googleapis.com/auth/devstorage.read_write']); - } - - // Create the service object. - var storage = google.storage('v1'); - - // Make the api call to list the buckets. - storage.buckets.list({ - auth: authClient, - project: projectId - }, function (err, response) { - if (err) { - return callback(err); - } - - console.log('Found ' + response.items.length + ' buckets'); - callback(null, response); - }); - }); -} -// [END list_buckets] - -// Run the samples -exports.main = function (projectId, cb) { - listBucketsExample(projectId, cb || function (err, response) { - console.log(err, response.items); - }); -}; - -if (module === require.main) { - exports.main(process.argv.slice(2).shift()); -} diff --git a/storage/buckets.js b/storage/buckets.js new file mode 100644 index 0000000000..3ab1c3950d --- /dev/null +++ b/storage/buckets.js @@ -0,0 +1,132 @@ +// 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'); + +// Get a reference to the storage component +var storage = gcloud.storage(); +// [END setup] + +// [START create] +/** + * Creates a new bucket with the given name. + * + * @param {string} name The name of the new bucket. + * @param {function} cb The callback function. + */ +function createBucketExample (name, callback) { + if (!name) { + return callback(new Error('"name" is required!')); + } + + // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage?method=createBucket + storage.createBucket(name, function (err, bucket, apiResponse) { + if (err) { + return callback(err); + } + + console.log('Created bucket: ' + name); + return callback(null, bucket); + }); +} +// [END create] + +// [START list] +/** + * Fetches all of the current project's buckets. + * + * @param {function} cb The callback function. + */ +function listBucketsExample (callback) { + // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage?method=getBuckets + storage.getBuckets(function (err, buckets, apiResponse) { + if (err) { + return callback(err); + } + + console.log('Found ' + buckets.length + ' buckets!'); + return callback(null, buckets, apiResponse); + }); +} +// [END list] + +// [START delete] +/** + * Deletes the specified bucket. + * + * @param {string} name The name of the bucket to delete. + * @param {function} cb The callback function. + */ +function deleteBucketExample (name, callback) { + if (!name) { + return callback(new Error('"name" is required!')); + } + + // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage?method=bucket + var bucket = storage.bucket(name); + + // See https://googlecloudplatform.github.io/gcloud-node/#/docs/storage/bucket?method=delete + bucket.delete(function (err, apiResponse) { + if (err) { + return callback(err); + } + + console.log('Deleted bucket: ' + name); + return callback(null, apiResponse); + }); +} +// [END delete] + +// [START usage] +function printUsage () { + console.log('Usage: node buckets [COMMAND] [ARGS...]'); + console.log('\nCommands:\n'); + console.log('\tcreate [BUCKET_NAME]'); + console.log('\tlist'); + console.log('\tdelete [BUCKET_NAME]'); +} +// [END usage] + +// Run the command-line program +function main (args, cb) { + var command = args.shift(); + if (command === 'create') { + createBucketExample(args[0], cb); + } else if (command === 'list') { + listBucketsExample(cb); + } else if (command === 'delete') { + deleteBucketExample(args[0], cb); + } else { + printUsage(); + cb(); + } +} + +if (module === require.main) { + main(process.argv.slice(2), console.log); +} +// [END all] + +exports.createBucketExample = createBucketExample; +exports.listBucketsExample = listBucketsExample; +exports.deleteBucketExample = deleteBucketExample; +exports.printUsage = printUsage; +exports.main = main; diff --git a/storage/package.json b/storage/package.json index eb0cb67950..e8adcd5dbf 100644 --- a/storage/package.json +++ b/storage/package.json @@ -9,9 +9,9 @@ "system-test": "mocha -R spec -t 120000 --require intelli-espower-loader ../system-test/_setup.js system-test/*.test.js" }, "dependencies": { - "googleapis": "^12.0.0" + "gcloud": "^0.37.0" }, "devDependencies": { - "mocha": "^2.5.3" + "mocha": "^3.0.1" } } diff --git a/storage/system-test/authSample.test.js b/storage/system-test/authSample.test.js deleted file mode 100644 index dccd11db19..0000000000 --- a/storage/system-test/authSample.test.js +++ /dev/null @@ -1,35 +0,0 @@ -// 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. - -/** - * @fileoverview Tests for the list-buckets module. - */ -'use strict'; - -var authSampleExample = require('../authSample'); -var projectId = process.env.GCLOUD_PROJECT; - -describe('storage:authSample', function () { - it('should return a list of buckets', function (done) { - var bucketName = process.env.TEST_BUCKET_NAME || 'nodejs-docs-samples'; - - authSampleExample.main(projectId, function (err, response) { - assert(!err); - assert(response.items.length > 0, 'There should be some buckets.'); - assert(response.items.filter(function (item) { - return item.name === bucketName; - }).length === 1, 'There should be a bucket named ' + bucketName); - done(); - }); - }); -}); diff --git a/storage/system-test/buckets.test.js b/storage/system-test/buckets.test.js new file mode 100644 index 0000000000..d050dbb2f0 --- /dev/null +++ b/storage/system-test/buckets.test.js @@ -0,0 +1,51 @@ +// 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 bucketsExample = require('../buckets'); +var bucketName = '' + new Date().getTime() + Math.floor(Math.random() * 100000000); + +describe('storage:buckets', function () { + describe('create', function () { + it('should create a bucket', function (done) { + bucketsExample.createBucketExample(bucketName, function (err, bucket) { + assert.ifError(err); + assert.equal(bucket.name, bucketName); + assert(console.log.calledWith('Created bucket: ' + bucketName)); + done(); + }); + }); + }); + describe('list', function () { + it('should list buckets', function (done) { + bucketsExample.listBucketsExample(function (err, buckets) { + assert.ifError(err); + assert(Array.isArray(buckets)); + assert(buckets.length > 0); + assert(console.log.calledWith('Found ' + buckets.length + ' buckets!')); + done(); + }); + }); + }); + describe('delete', function () { + it('should delete a bucket', function (done) { + bucketsExample.deleteBucketExample(bucketName, function (err, apiResponse) { + assert.ifError(err); + console.log(apiResponse); + assert(console.log.calledWith('Deleted bucket: ' + bucketName)); + done(); + }); + }); + }); +}); diff --git a/storage/test/authSample.test.js b/storage/test/authSample.test.js deleted file mode 100644 index 5c3c7c2a00..0000000000 --- a/storage/test/authSample.test.js +++ /dev/null @@ -1,18 +0,0 @@ -// 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'; - -describe('storage:authSample', function () { - it('should be tested'); -}); diff --git a/storage/test/buckets.test.js b/storage/test/buckets.test.js new file mode 100644 index 0000000000..546cc0fcdc --- /dev/null +++ b/storage/test/buckets.test.js @@ -0,0 +1,173 @@ +// 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 = { + delete: sinon.stub().callsArgWith(0, null) + }; + var storageMock = { + createBucket: sinon.stub().callsArgWith(1, null, bucketsMock[0]), + getBuckets: sinon.stub().callsArgWith(0, null, bucketsMock, null, bucketsMock), + bucket: sinon.stub().returns(bucketMock) + }; + var gcloudMock = { + storage: sinon.stub().returns(storageMock) + }; + return { + sample: proxyquire('../buckets', { + gcloud: gcloudMock + }), + mocks: { + gcloud: gcloudMock, + storage: storageMock, + buckets: bucketsMock, + bucket: bucketMock + } + }; +} + +describe('storage:buckets', function () { + describe('create', function () { + it('should create a bucket', function () { + var bucketsSample = getSample(); + + bucketsSample.sample.createBucketExample(bucketName, function (err, bucket) { + assert.ifError(err); + assert.strictEqual(bucket, bucketsSample.mocks.buckets[0]); + assert(console.log.calledWith('Created bucket: ' + bucketName)); + }); + }); + it('should require name', function () { + var bucketsSample = getSample(); + + bucketsSample.sample.createBucketExample(undefined, function (err, bucket) { + assert(err); + assert(err.message = '"name" is required!'); + assert.equal(bucket, undefined); + }); + }); + it('should handle error', function () { + var error = 'createError'; + var bucketsSample = getSample(); + bucketsSample.mocks.storage.createBucket = sinon.stub().callsArgWith(1, error); + + bucketsSample.sample.createBucketExample(bucketName, function (err, bucket) { + assert.equal(err, error); + assert.equal(bucket, undefined); + }); + }); + }); + describe('list', function () { + it('should list buckets', function () { + var bucketsSample = getSample(); + + bucketsSample.sample.listBucketsExample(function (err, buckets) { + assert.ifError(err); + assert.strictEqual(buckets, bucketsSample.mocks.buckets); + assert(console.log.calledWith('Found 1 buckets!')); + }); + }); + it('should handle error', function () { + var error = 'listError'; + var bucketsSample = getSample(); + bucketsSample.mocks.storage.getBuckets = sinon.stub().callsArgWith(0, error); + + bucketsSample.sample.listBucketsExample(function (err, buckets) { + assert.equal(err, error); + assert.equal(buckets, undefined); + }); + }); + }); + describe('delete', function () { + it('should delete a bucket', function () { + var bucketsSample = getSample(); + + bucketsSample.sample.deleteBucketExample(bucketName, function (err, apiResponse) { + assert.ifError(err); + assert.equal(bucketsSample.mocks.storage.bucket.firstCall.args[0], bucketName); + assert(console.log.calledWith('Deleted bucket: ' + bucketName)); + }); + }); + it('should require name', function () { + var bucketsSample = getSample(); + + bucketsSample.sample.deleteBucketExample(undefined, function (err, apiResponse) { + assert(err); + assert(err.message = '"name" is required!'); + assert.equal(apiResponse, undefined); + }); + }); + it('should handle error', function () { + var error = 'deleteError'; + var bucketsSample = getSample(); + bucketsSample.mocks.bucket.delete = sinon.stub().callsArgWith(0, error); + + bucketsSample.sample.deleteBucketExample(bucketName, function (err, apiResponse) { + assert.equal(err, error); + assert.equal(apiResponse, undefined); + }); + }); + }); + describe('main', function () { + it('should call the right commands', function () { + var bucketsSample = getSample(); + + bucketsSample.sample.main(['create', bucketName], function (err, bucket) { + assert.ifError(err); + assert.strictEqual(bucket, bucketsSample.mocks.buckets[0]); + assert(console.log.calledWith('Created bucket: ' + bucketName)); + }); + bucketsSample.sample.main(['list'], function (err, buckets) { + assert.ifError(err); + assert.strictEqual(buckets, bucketsSample.mocks.buckets); + assert(console.log.calledWith('Found 1 buckets!')); + }); + bucketsSample.sample.main(['delete', bucketName], function (err, apiResponse) { + assert.ifError(err); + assert.equal(bucketsSample.mocks.storage.bucket.firstCall.args[0], bucketName); + assert(console.log.calledWith('Deleted bucket: ' + bucketName)); + }); + bucketsSample.sample.main(['foo'], function () { + 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('\tlist')); + assert(console.log.calledWith('\tdelete [BUCKET_NAME]')); + }); + }); + }); + describe('printUsage', function () { + it('should print usage', function () { + var bucketsSample = getSample(); + + bucketsSample.sample.printUsage(); + + 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('\tlist')); + assert(console.log.calledWith('\tdelete [BUCKET_NAME]')); + }); + }); +});