Skip to content

Commit

Permalink
storage: add move function to File
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed May 6, 2015
1 parent f145a7f commit 4a9a1e0
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 0 deletions.
81 changes: 81 additions & 0 deletions lib/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,87 @@ File.prototype.copy = function(destination, callback) {
});
};

/**
* Move this file to another location. By default, this will move
* the file to the same bucket, but you can choose to move it
* to another Bucket by providing either a Bucket or File object.
*
* @throws {Error} If the destination file is not provided.
*
* @param {string|module:storage/bucket|module:storage/file} destination -
* Destination file.
* @param {function=} callback - The callback function.
*
* @example
* //-
* // You can pass in a variety of types for the destination.
* //
* // For all of the below examples, assume we are working with the following
* // Bucket and File objects.
* //-
* var bucket = storage.bucket('my-bucket');
* var file = bucket.file('my-image.png');
*
* //-
* // If you pass in a string for the destination, the file is moved to its
* // current bucket, under the new name provided.
* //-
* file.move('my-image-new.png', function(err, destinationFile, apiResponse) {
* // `my-bucket` no longer contains:
* // - "my-image.png"
* // but contains instead:
* // - "my-image-new.png"
*
* // `destinationFile` is an instance of a File object that refers
* // to your new file.
* });
*
* //-
* // If you pass in a Bucket object, the file will be moved to that bucket
* // using the same name.
* //-
* var anotherBucket = storage.bucket('another-bucket');
* file.move(anotherBucket, function(err, destinationFile, apiResponse) {
* // `my-bucket` no longer contains:
* // - "my-image.png"
* //
* // `another-bucket` now contains:
* // - "my-image.png"
*
* // `destinationFile` is an instance of a File object that refers
* // to your new file.
* });
*
* //-
* // If you pass in a File object, you have complete control over the new
* // bucket and filename.
* //-
* var anotherFile = anotherBucket.file('my-awesome-image.png');
* file.move(anotherFile, function(err, destinationFile, apiResponse) {
* // `my-bucket` no longer contains:
* // - "my-image.png"
* //
* // `another-bucket` now contains:
* // - "my-awesome-image.png"
*
* // Note:
* // The `destinationFile` parameter is equal to `anotherFile`.
* });
*/
File.prototype.move = function(destination, callback) {
callback = callback || util.noop;
var deleteFunction = this.delete.bind(this);
this.copy(destination, function(err, destinationFile, apiResponse) {
if (err) {
callback(err, null, apiResponse);
} else {
deleteFunction(function(err, apiResponse) {
callback(err, destinationFile, apiResponse);
});
}
});
};

/**
* Create a readable stream to read the contents of the remote file. It can be
* piped to a writable stream or listened to for 'data' events to read a file's
Expand Down
88 changes: 88 additions & 0 deletions test/storage/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,94 @@ describe('File', function() {
});
});

describe('move', function() {
it('should throw if no destination is provided', function() {
assert.throws(function() {
file.move();
}, /should have a name/);
});

describe('copy to destination', function() {
function assertCopyFile(file, expectedDestination, callback) {
file.copy = function(destination) {
assert.equal(destination, expectedDestination);
callback();
};
}

it('should call copy with string', function(done) {
var newFileName = 'new-file-name.png';
assertCopyFile(file, newFileName, done);
file.move(newFileName);
});

it('should call copy with Bucket', function(done) {
var newBucket = new Bucket({}, 'new-bucket');
assertCopyFile(file, newBucket, done);
file.move(newBucket);
});

it('should call copy with File', function(done) {
var newBucket = new Bucket({}, 'new-bucket');
var newFile = new File(newBucket, 'new-file');
assertCopyFile(file, newFile, done);
file.move(newFile);
});

it('should fail if copy fails', function(done) {
var error = new Error('Error.');
file.copy = function(destination, callback) {
callback(error);
};
file.move('new-filename', function(err) {
assert.equal(err, error);
done();
});
});
});

describe('delete original file', function() {
it('should delete if copy is successful', function(done) {
file.copy = function(destination, callback) {
callback(null);
};
file.delete = function() {
assert.equal(this, file);
done();
};
file.move('new-filename');
});

it('should not delete if copy fails', function(done) {
var deleteCalled = false;
file.copy = function(destination, callback) {
callback(new Error('Error.'));
};
file.delete = function() {
deleteCalled = true;
};
file.move('new-filename', function() {
assert.equal(deleteCalled, false);
done();
});
});

it('should fail if delete fails', function(done) {
var error = new Error('Error.');
file.copy = function(destination, callback) {
callback();
};
file.delete = function(callback) {
callback(error);
};
file.move('new-filename', function(err) {
assert.equal(err, error);
done();
});
});
});
});

describe('createReadStream', function() {
it('should create an authorized request', function(done) {
var expectedPath = util.format('https://{b}.storage.googleapis.com/{o}', {
Expand Down

0 comments on commit 4a9a1e0

Please sign in to comment.