Permalink
Browse files

[api test] Added methods and tests for StorageObjects and Containers.

  • Loading branch information...
1 parent b84a993 commit 99daf92d740dd32341cc5df8d67d22926a367aec @indexzero indexzero committed Oct 10, 2010
View
@@ -13,8 +13,8 @@ var Config = function () {
Config.prototype = {
// Remark: Put your Rackspace API Key here
auth: {
- username: 'your-username',
- apiKey: 'your-api-key'
+ username: 'nodejitsudev',
+ apiKey: '96d15003f9503e24a9a43ee232c2d14d'
},
cdn: {
@@ -24,8 +24,9 @@ var Container = function (details) {
};
Container.prototype = {
+ // Remark: Not fully implemented
addFile: function (file, data, callback) {
-
+ cloudfiles.addFile(this.name, file, data, callback);
},
destory: function (callback) {
@@ -36,13 +37,15 @@ Container.prototype = {
var self = this;
cloudfiles.getFiles(this.name, function (err, files) {
self.files = files;
+ callback(null, files);
});
},
removeFile: function (file, callback) {
-
+ cloudfiles.destroyFile(this.name, file, callback);
},
+ // Remark: Not fully implemented
updateCdn: function (options, callback) {
if (!this.cdnEnabled) {
callback(new Error('Cannot call updateCdn on a container that is not CDN enabled'));
View
@@ -70,12 +70,12 @@ core.getContainer = function () {
var args = Array.prototype.slice.call(arguments),
callback = (typeof(args[args.length - 1]) === 'function') && args.pop(),
isCdn = args.length > 0 && (typeof(args[args.length - 1]) === 'boolean') && args.pop(),
- container = args.pop(),
- url = isCdn ? utils.cdnUrl(container) : utils.storageUrl(container);
-
+ containerName = args.pop(),
+ url = isCdn ? utils.cdnUrl(containerName) : utils.storageUrl(containerName);
+
utils.rackspace('HEAD', url, callback, function (body, res) {
var container = {
- name: container,
+ name: containerName,
count: new Number(res.headers['x-container-object-count']),
bytes: new Number(res.headers['x-container-bytes-used'])
};
@@ -134,12 +134,16 @@ core.getFiles = function (container, callback) {
});
};
-core.getFile = function (container, file, callback) {
- utils.rackspace(utils.storageUrl(container, file), callback, function (body, res) {
+core.getFile = function (container, fileName, callback) {
+ utils.rackspace(utils.storageUrl(container, fileName), callback, function (body, res) {
var file = {
content_type: res.headers['content-type'],
bytes: res.headers['content-length'],
- data: body
+ hash: res.headers['etag'],
+ last_modified: res.headers['last-modified'],
+ data: body,
+ container: container,
+ name: fileName
};
callback(null, new (cloudfiles.StorageObject)(file));
@@ -21,37 +21,79 @@ var StorageObject = function (details) {
this._setProperties(details);
};
+function clone(obj) {
+ var clone = {};
+ for (var i in obj) {
+ clone[i] = obj[i];
+ }
+ return clone;
+}
+
StorageObject.prototype = {
+ // Remark: Not fully implemented
addMetadata: function (metadata, callback) {
+ var newMetadata = clone(this.metadata);
+ Object.keys(metadata).forEach(function (key) {
+ newMetadata[key] = metadata[key];
+ });
+
+ var options = {
+ uri: this.fullPath,
+ method: 'POST',
+ headers: this._createHeaders(newMetadata)
+ };
+ utils.rackspace(options, callback, function (body, res) {
+ this.metadata = newMetadata;
+ callback(null, true);
+ });
},
- copy: function (destination, callback) {
+ // Remark: This method is untested
+ copy: function (container, destination, callback) {
var copyOptions = {
method: 'PUT',
uri: this.fullPath,
headers: {
- 'X-COPY-DESTINATION': destination,
+ 'X-COPY-DESTINATION': [container, destination].join('/'),
'CONTENT-LENGTH': this.bytes
}
};
utils.rackspace(copyOptions, callback, function (body, res) {
- eyes.inspect(body);
- eyes.inspect(res.statusCode);
+ callback(null, true);
});
},
destroy: function (callback) {
cloudfiles.destroyFile(this.containerName, this.name, callback);
},
- getMetadata: function () {
-
+ // Remark: Not fully implemented
+ getMetadata: function (callback) {
+ utils.rackspace('HEAD', this.fullPath, function (body, res) {
+ var metadata = {};
+ Object.keys(res.headers).forEach(function (header) {
+ var match;
+ if (match = header.match(/x-object-meta-(\w+)/i)) {
+ metadata[match[1]] = res.headers[header];
+ }
+ });
+
+ callback(null, metadata);
+ });
},
+ // Remark: Not fully implemented
removeMetadata: function (keys, callback) {
+ var newMetadata = {};
+ Object.keys(this.metadata).forEach(function (key) {
+ if (keys.indexOf(key) !== -1) {
+ newMetadata[key] = this.metadata[key];
+ }
+ });
+ // TODO: Finish writing this method
},
update: function (data, callback) {
@@ -67,13 +109,26 @@ StorageObject.prototype = {
},
_setProperties: function (details) {
+ // TODO: Should probably take this in from details or something.
+ this.metadata = {};
+
this.container = details.container;
this.name = details.name;
this.hash = details.hash;
this.bytes = details.bytes;
this.data = details.data;
this.contentType = details.content_type;
this.lastModified = details.last_modified;
+ },
+
+ _createHeaders: function (metadata) {
+ var headers = {};
+ Object.keys(metadata).forEach(function (key) {
+ var header = "x-object-meta-" + key;
+ headers[header] = metadata[key];
+ });
+
+ return headers;
}
};
View
@@ -108,7 +108,7 @@ utils.rackspace = function () {
else if (typeof requestBody !== 'undefined') {
serverOptions.body = requestBody;
}
-
+
request(serverOptions, function (err, res, body) {
if (err) {
if (callback) {
View
@@ -7,6 +7,7 @@
*/
var path = require('path'),
+ fs = require('fs'),
vows = require('vows'),
eyes = require('eyes'),
helpers = require('./helpers')
@@ -16,6 +17,9 @@ require.paths.unshift(path.join(__dirname, '..', 'lib'));
var cloudfiles = require('cloudfiles');
+var sampleData = fs.readFileSync(path.join(__dirname, '..', 'test', 'data', 'fillerama.txt')).toString(),
+ testData = {};
+
vows.describe('node-cloudfiles/containers').addBatch({
"The node-cloudfiles client": {
"when authenticated": {
@@ -97,6 +101,7 @@ vows.describe('node-cloudfiles/containers').addBatch({
},
"should return a valid container": function (err, container) {
helpers.assertContainer(container);
+ testData.container = container;
}
},
"when requesting CDN container": {
@@ -119,4 +124,46 @@ vows.describe('node-cloudfiles/containers').addBatch({
}
}
}
+}).addBatch({
+ "The node-cloudfiles client": {
+ "an instance of a Container object": {
+ "the addFile() method": {
+ topic: function () {
+ testData.container.addFile('file1.txt', sampleData, this.callback);
+ },
+ "should response with true": function (err, added) {
+ assert.isTrue(added);
+ }
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "an instance of a Container object": {
+ "the getFiles() method": {
+ topic: function () {
+ testData.container.getFiles(this.callback);
+ },
+ "should response with a list of files": function (err, files) {
+ assert.isArray(files);
+ assert.length(files, 1);
+ assert.isArray(testData.container.files);
+ assert.length(testData.container.files, 1);
+ }
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "an instance of a Container object": {
+ "the removeFile() method": {
+ topic: function () {
+ testData.container.removeFile('file1.txt', this.callback);
+ },
+ "should response with true": function (err, removed) {
+ assert.isTrue(removed);
+ }
+ }
+ }
+ }
}).export(module);
@@ -0,0 +1,96 @@
+/*
+ * container-test.js: Tests for rackspace cloudfiles containers
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ eyes = require('eyes'),
+ fs = require('fs'),
+ helpers = require('./helpers')
+ assert = require('assert');
+
+require.paths.unshift(path.join(__dirname, '..', 'lib'));
+
+var cloudfiles = require('cloudfiles');
+
+var sampleData = fs.readFileSync(path.join(__dirname, '..', 'test', 'data', 'fillerama.txt')).toString(),
+ testData = {};
+
+vows.describe('node-cloudfiles/storage-object').addBatch({
+ "The node-cloudfiles client": {
+ "when authenticated": {
+ topic: function () {
+ var options = cloudfiles.config
+ cloudfiles.setAuth(options.auth, this.callback);
+ },
+ "should return with 204": function (err, res) {
+ assert.equal(res.statusCode, 204);
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "the addFile() method": {
+ topic: function () {
+ cloudfiles.addFile('test_container', 'file1.txt', sampleData, this.callback);
+ },
+ "should respond with true": function (err, uploaded) {
+ assert.isTrue(uploaded);
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "the getFile() method": {
+ "for a file that exists": {
+ topic: function () {
+ cloudfiles.getFile('test_container', 'file1.txt', this.callback);
+ },
+ "should return a valid StorageObject": function (err, file) {
+ assert.equal(file.data.length, sampleData.length);
+ helpers.assertFile(file);
+ testData.file = file;
+ }
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "the addMetadata() method": {
+ topic: function () {
+ testData.file.addMetadata({ "ninja": "true" }, this.callback);
+ },
+ "should response with true": function (err, added) {
+ assert.isTrue(added);
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "the getMetadata() method": {
+ topic: function () {
+ testData.file.getMetadata(this.callback);
+ },
+ "should response with true": function (err, added) {
+ assert.isTrue(added);
+ }
+ }
+ }
+}).addBatch({
+ "The node-cloudfiles client": {
+ "the destroyFile() method": {
+ "for a file that exists": {
+ topic: function () {
+ cloudfiles.destroyFile('test_container', 'file1.txt', this.callback);
+ },
+ "should return true": function (err, deleted) {
+ assert.isTrue(deleted);
+ }
+ }
+ }
+ }
+}).export(module);
Oops, something went wrong.

0 comments on commit 99daf92

Please sign in to comment.