Permalink
Browse files

[api test] Added methods for container and file manipulation

  • Loading branch information...
1 parent 22c29f8 commit 00a3268a95efb3e98c4aeebdbf3168966e6f4692 @indexzero indexzero committed Sep 28, 2010
View
@@ -11,15 +11,19 @@ require.paths.unshift(__dirname);
var cloudfiles = exports;
// Core
-cloudfiles.config = require('cloudfiles/config').config;
-cloudfiles.setAuth = require('cloudfiles/core').setAuth;
+cloudfiles.config = require('cloudfiles/config').config;
+cloudfiles.setAuth = require('cloudfiles/core').setAuth;
// Containers
-cloudfiles.Container = require('cloudfiles/container').Container;
-cloudfiles.createContainer = require('cloudfiles/core').createContainer;
-cloudfiles.getContainers = require('cloudfiles/core').getContainers;
-cloudfiles.getContainer = require('cloudfiles/core').getContainer;
+cloudfiles.Container = require('cloudfiles/container').Container;
+cloudfiles.createContainer = require('cloudfiles/core').createContainer;
+cloudfiles.getContainers = require('cloudfiles/core').getContainers;
+cloudfiles.getContainer = require('cloudfiles/core').getContainer;
+cloudfiles.destroyContainer = require('cloudfiles/core').destroyContainer;
// Storage Object
-cloudfiles.StorageObject = require('cloudfiles/storage-object').StorageObject;
-cloudfiles.getFiles = require('cloudfiles/core').getFiles;
+cloudfiles.StorageObject = require('cloudfiles/storage-object').StorageObject;
+cloudfiles.getFiles = require('cloudfiles/core').getFiles;
+cloudfiles.getFile = require('cloudfiles/core').getFile;
+cloudfiles.addFile = require('cloudfiles/core').addFile;
+cloudfiles.destroyFile = require('cloudfiles/core').destroyFile;
View
@@ -13,9 +13,14 @@ var Config = function () {
Config.prototype = {
// Remark: Put your Rackspace API Key here
auth: {
- username: 'your-username',
- apiKey: 'your-api-key'
+ username: 'nodejitsudev',
+ apiKey: 'a11e9c09bebbea62c1e0ab5f5a81b545'
},
+
+ cdn: {
+ ttl: 43200, // Default X-TTL time-out to 12 hours,
+ logRetention: true // Default X-LOG-RETENTION to true
+ }
};
exports.config = new (Config);
@@ -10,6 +10,7 @@ require.paths.unshift(require('path').join(__dirname, '..'));
var cloudfiles = require('cloudfiles'),
eyes = require('eyes'),
+ pool = require('pool'),
sys = require('sys'),
utils = require('./utils');
@@ -23,10 +24,33 @@ var Container = function (details) {
};
Container.prototype = {
- destory: function () {
+ addFile: function (file, data, callback) {
},
+ destory: function (callback) {
+ cloudfiles.destoryContainer(this.name, callback);
+ },
+
+ getFiles: function (callback) {
+ var self = this;
+ cloudfiles.getFiles(this.name, function (err, files) {
+ self.files = files;
+ });
+ },
+
+ removeFile: function (file, callback) {
+
+ },
+
+ updateCdn: function (options, callback) {
+ if (!this.cdnEnabled) {
+ callback(new Error('Cannot call updateCdn on a container that is not CDN enabled'));
+ }
+
+ // TODO: Write the rest of this method
+ },
+
_setProperties: function (details) {
this.name = details.name;
this.cdnEnabled = details.cdnEnabled || false;
View
@@ -50,9 +50,13 @@ core.setAuth = function (options, callback) {
});
};
-// Remark: What about CDN Containers?
-core.getContainers = function (callback) {
- utils.rackspace(utils.storageUrl(true), callback, function (body) {
+core.getContainers = 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(),
+ url = isCdn ? utils.cdnUrl(true) : utils.storageUrl(true);
+
+ utils.rackspace(url, callback, function (body) {
var results = [], containers = JSON.parse(body);
containers.forEach(function (container) {
results.push(new (cloudfiles.Container)(container));
@@ -62,9 +66,14 @@ core.getContainers = function (callback) {
});
};
-// Remark: What about CDN Containers?
-core.getContainer = function (container, callback) {
- utils.rackspace('HEAD', utils.storageUrl(container), callback, function (body, res) {
+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);
+
+ utils.rackspace('HEAD', url, callback, function (body, res) {
var container = {
name: container,
count: new Number(res.headers['x-container-object-count']),
@@ -100,6 +109,20 @@ core.createContainer = function (container, callback) {
});
};
+core.destroyContainer = function (container, callback) {
+ core.getFiles(container, function (err, files) {
+ if (err) {
+ callback(err);
+ return;
+ }
+
+ // TODO: Delete all files, then delete the container
+ utils.rackspace('DELETE', utils.storageUrl(container), callback, function (body, res) {
+ callback(null, true);
+ });
+ });
+};
+
core.getFiles = function (container, callback) {
utils.rackspace(utils.storageUrl(container, true), callback, function (body) {
var results = [], files = JSON.parse(body);
@@ -110,3 +133,38 @@ core.getFiles = function (container, callback) {
callback(null, results);
});
};
+
+core.getFile = function (container, file, callback) {
+ utils.rackspace(utils.storageUrl(container, file), callback, function (body, res) {
+ var file = {
+ content_type: res.headers['content-type'],
+ bytes: res.headers['content-length'],
+ data: body
+ };
+
+ callback(null, new (cloudfiles.StorageObject)(file));
+ });
+};
+
+core.addFile = function (container, file, data, callback) {
+ var options = {
+ method: 'PUT',
+ uri: utils.storageUrl(container, file),
+ body: data,
+ headers: {
+ 'Transfer-Encoding': 'chunked',
+ // TODO: We should be determining MIME-TYPE somehow
+ 'Content-Type': 'text/plain; charset=UTF-8'
+ }
+ };
+
+ utils.rackspace(options, callback, function (body, res) {
+ callback(null, true);
+ });
+};
+
+core.destroyFile = function (container, file, callback) {
+ utils.rackspace('DELETE', utils.storageUrl(container, file), function (body, res) {
+ callback(null, true);
+ });
+};
@@ -22,12 +22,17 @@ var StorageObject = function (details) {
};
StorageObject.prototype = {
+ addMetadata: function (metadata, callback) {
+
+ },
+
copy: function (destination, callback) {
var copyOptions = {
- method: 'COPY',
+ method: 'PUT',
uri: this.fullPath,
headers: {
- 'Destination': destination
+ 'X-COPY-DESTINATION': destination,
+ 'CONTENT-LENGTH': this.bytes
}
};
@@ -44,13 +49,15 @@ StorageObject.prototype = {
});
},
- // Adds metadata to this instance .... getter / setter?
- addMetadata: function () {
+ getMetadata: function () {
+
+ },
+
+ removeMetadata: function (keys, callback) {
},
- // Updates this instance with a new target bytes??
- update: function () {
+ update: function (data, callback) {
},
@@ -64,6 +71,7 @@ StorageObject.prototype = {
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;
}
View
@@ -101,9 +101,12 @@ utils.rackspace = function () {
headers: headers
};
- if (typeof requestBody !== 'undefined') {
+ if (typeof requestBody !== 'undefined' && !serverOptions.headers['Content-Type']) {
serverOptions.headers['Content-Type'] = 'application/json';
serverOptions.body = JSON.stringify(requestBody);
+ }
+ else if (typeof requestBody !== 'undefined') {
+ serverOptions.body = requestBody;
}
request(serverOptions, function (err, res, body) {
@@ -0,0 +1,52 @@
+/*
+ * container-test.js: Tests for rackspace cloudfiles containers
+ *
+ * (C) 2010 Charlie Robbins
+ * MIT LICENSE
+ *
+ */
+
+var path = require('path'),
+ vows = require('vows'),
+ eyes = require('eyes'),
+ helpers = require('./helpers')
+ assert = require('assert');
+
+require.paths.unshift(path.join(__dirname, '..', 'lib'));
+
+var cloudfiles = require('cloudfiles');
+
+vows.describe('node-cloudfiles/containers').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 destroyContainer() method": {
+ "when deleting test_container": {
+ topic: function () {
+ cloudfiles.destroyContainer('test_container', this.callback)
+ },
+ "should return true": function (err, success) {
+ assert.isTrue(success);
+ }
+ },
+ "when deleting test_cdn_container": {
+ topic: function () {
+ cloudfiles.destroyContainer('test_cdn_container', this.callback)
+ },
+ "should return true": function (err, success) {
+ assert.isTrue(success);
+ }
+ }
+ }
+ }
+}).export(module);
View
@@ -54,22 +54,68 @@ vows.describe('node-cloudfiles/containers').addBatch({
}
}).addBatch({
"The node-cloudfiles client": {
+ "the createContainer() method": {
+ "when creating a container that already exists": {
+ topic: function () {
+ cloudfiles.createContainer({ name: 'test_container' }, this.callback);
+ },
+ "should return a valid container": function (err, container) {
+ helpers.assertContainer(container);
+ }
+ },
+ },
"the getContainers() method": {
- topic: function () {
- cloudfiles.getContainers(this.callback);
+ "when requesting non-CDN containers": {
+ topic: function () {
+ cloudfiles.getContainers(this.callback);
+ },
+ "should return a list of containers": function (err, containers) {
+ assert.isArray(containers);
+ assert.length(containers, 2);
+ containers.forEach(function (container) {
+ helpers.assertContainer(container);
+ });
+ }
},
- "should return a list of containers": function (err, containers) {
- containers.forEach(function (container) {
- helpers.assertContainer(container);
- });
+ "when requesting CDN containers": {
+ topic: function () {
+ cloudfiles.getContainers(true, this.callback);
+ },
+ "should return a list of containers": function (err, containers) {
+ assert.isArray(containers);
+ assert.length(containers, 1);
+ containers.forEach(function (container) {
+ helpers.assertContainer(container);
+ });
+ }
}
},
"the getContainer() method": {
- topic: function () {
- cloudfiles.getContainer('test_container', this.callback);
+ "when requesting non-CDN container": {
+ topic: function () {
+ cloudfiles.getContainer('test_container', this.callback);
+ },
+ "should return a valid container": function (err, container) {
+ helpers.assertContainer(container);
+ }
},
- "should return a valid container": function (err, container) {
- helpers.assertContainer(container);
+ "when requesting CDN container": {
+ "with a valid CDN container": {
+ topic: function () {
+ cloudfiles.getContainer('test_cdn_container', true, this.callback);
+ },
+ "should return a valid container": function (err, container) {
+ helpers.assertContainer(container);
+ }
+ },
+ "with an invalid CDN container": {
+ topic: function () {
+ cloudfiles.getContainer('test_container', true, this.callback);
+ },
+ "should respond with an error": function (err, container) {
+ assert.isNotNull(err);
+ }
+ }
}
}
}
View
@@ -0,0 +1,9 @@
+Yes, I saw. You were doing well, until everyone died. You seem malnourished. Are you suffering from intestinal parasites? We're rescuing ya. Now what? Say what? Yes. You gave me a dollar and some candy.
+
+No, I'm Santa Claus! Moving along… Oh, I always feared he might run off like this. Why, why, why didn't I break his legs? Robot 1-X, save my friends! And Zoidberg! Are you crazy? I can't swallow that. For the last time, I don't like lilacs! Your 'first' wife was the one who liked lilacs!
+
+You can see how I lived before I met you. Then we'll go with that data file! Now, now. Perfectly symmetrical violence never solved anything.
+
+Throw her in the brig. Oh, I don't have time for this. I have to go and buy a single piece of fruit with a coupon and then return it, making people wait behind me while I complain. Say it in Russian! Oh no! The professor will hit me! But if Zoidberg 'fixes' it... then perhaps gifts! I had more, but you go ahead. Ow, my spirit!
+
+You're going back for the Countess, aren't you? You've killed me! Oh, you've killed me! No. We're on the top. Bite my shiny metal ass.
Oops, something went wrong.

0 comments on commit 00a3268

Please sign in to comment.