aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/webcals/request/abstract.js12
-rw-r--r--lib/webcals/request/propfind.js56
-rw-r--r--test/webcals/request/abstract_test.js10
-rw-r--r--test/webcals/request/propfind_test.js109
4 files changed, 175 insertions, 12 deletions
diff --git a/lib/webcals/request/abstract.js b/lib/webcals/request/abstract.js
index fe47de9..ac0ceb5 100644
--- a/lib/webcals/request/abstract.js
+++ b/lib/webcals/request/abstract.js
@@ -25,16 +25,14 @@
this[key] = options[key];
}
}
+
+ this.xhr = new XHR({
+ url: this.url
+ });
}
Abstract.prototype = {
- _createXhr: function() {
- return new XHR({
- url: this.url
- });
- },
-
_createPayload: function() {
return '';
},
@@ -48,7 +46,7 @@
*/
send: function(callback) {
var self = this;
- var req = this.xhr = this._createXhr();
+ var req = this.xhr;
req.data = this._createPayload();
// in the future we may stream data somehow
diff --git a/lib/webcals/request/propfind.js b/lib/webcals/request/propfind.js
new file mode 100644
index 0000000..9e06b49
--- /dev/null
+++ b/lib/webcals/request/propfind.js
@@ -0,0 +1,56 @@
+(function(module, ns) {
+
+ var Abstract = ns.require('request/abstract'),
+ Template = ns.require('template'),
+ DavResponse = ns.require('sax/dav_response');
+
+ /**
+ * Creates a propfind request.
+ *
+ * @param {String} url location to make request.
+ * @param {Object} options options for propfind.
+ */
+ function Propfind(url, options) {
+ Abstract.apply(this, arguments);
+
+ this.template = new Template('propfind');
+ this._props = [];
+ this.sax.registerHandler(
+ 'DAV:/response',
+ DavResponse
+ );
+
+ this.xhr.headers['Depth'] = this.depth;
+ this.xhr.method = 'PROPFIND';
+ }
+
+ Propfind.prototype = {
+ __proto__: Abstract.prototype,
+
+ depth: 0,
+
+ /**
+ * Adds property to request.
+ *
+ * @param {String|Array} tagDesc tag description.
+ * @param {Object} [attr] optional tag attrs.
+ */
+ prop: function(tagDesc, attr) {
+ this._props.push(this.template.tag(tagDesc, attr));
+ },
+
+ _createPayload: function() {
+ var content = this.template.tag('prop', this._props.join(''));
+ return this.template.render(content);
+ }
+
+ };
+
+ module.exports = Propfind;
+
+}.apply(
+ this,
+ (this.Webcals) ?
+ [Webcals('request/abstract'), Webcals] :
+ [module, require('../webcals')]
+));
diff --git a/test/webcals/request/abstract_test.js b/test/webcals/request/abstract_test.js
index 124a135..0acb42b 100644
--- a/test/webcals/request/abstract_test.js
+++ b/test/webcals/request/abstract_test.js
@@ -31,10 +31,10 @@ suite('webcals/request/abstract.js', function() {
FakeXhr.instances.length = 0;
});
- test('#_createXhr', function() {
- var result = subject._createXhr();
- assert.instanceOf(result, Xhr);
- assert.equal(result.url, url);
+ test('.xhr', function() {
+ var xhr = subject.xhr;
+ assert.instanceOf(xhr, Xhr);
+ assert.equal(xhr.url, url);
});
test('#_createPayload', function() {
@@ -84,7 +84,7 @@ suite('webcals/request/abstract.js', function() {
});
xhr = getXhr();
- xhr.respond(xml, 200);
+ xhr.respond(xml, 207);
});
test('on response', function() {
diff --git a/test/webcals/request/propfind_test.js b/test/webcals/request/propfind_test.js
new file mode 100644
index 0000000..998fd2f
--- /dev/null
+++ b/test/webcals/request/propfind_test.js
@@ -0,0 +1,109 @@
+requireRequest();
+
+suite('webcals/request/propfind', function() {
+ var Abstract,
+ Propfind,
+ FakeXhr,
+ Xhr,
+ Template,
+ oldXhrClass,
+ SaxResponse;
+
+ var url = 'http://google.com',
+ subject;
+
+ suiteSetup(function() {
+ Abstract = Webcals.require('request/abstract');
+ Propfind = Webcals.require('request/propfind');
+ SaxResponse = Webcals.require('sax/dav_response');
+ FakeXhr = Webcals.require('support/fake_xhr');
+ Template = Webcals.require('template');
+ Xhr = Webcals.require('xhr');
+
+ oldXhrClass = Xhr.prototype.xhrClass;
+ Xhr.prototype.xhrClass = FakeXhr;
+ });
+
+ suiteTeardown(function() {
+ Xhr.prototype.xhrClass = oldXhrClass;
+ });
+
+ setup(function() {
+ subject = new Propfind(url);
+ FakeXhr.instances.length = 0;
+ });
+
+ test('initializer', function() {
+ assert.instanceOf(subject, Abstract);
+ assert.instanceOf(subject.template, Template);
+ assert.deepEqual(subject._props, []);
+ assert.equal(
+ subject.sax.handles['DAV:/response'],
+ SaxResponse
+ );
+
+ assert.equal(subject.xhr.headers['Depth'], 0);
+ assert.equal(subject.xhr.method, 'PROPFIND');
+ });
+
+ test('#prop', function() {
+ var expected = subject.template.tag('test');
+
+ subject.prop('test');
+
+ assert.deepEqual(subject._props, [expected]);
+ });
+
+ test('#_createPayload', function() {
+ subject.prop('foo');
+ subject.prop('bar');
+
+ var tags = [
+ '<N0:foo />',
+ '<N0:bar />'
+ ].join('');
+
+ var expected = [
+ subject.template.doctype,
+ '<N0:propfind xmlns:N0="DAV:">',
+ '<N0:prop>', tags, '</N0:prop>',
+ '</N0:propfind>'
+ ].join('');
+
+ var result = subject._createPayload();
+
+ console.log(result);
+
+ assert.equal(subject._createPayload(), expected);
+ });
+
+ suite('integration', function() {
+ var xml,
+ data,
+ result,
+ xhr,
+ calledWith;
+
+ defineSample('xml/propget.xml', function(data) {
+ xml = data;
+ });
+
+ setup(function(done) {
+ subject.prop('foo');
+
+ subject.send(function(err, tree) {
+ data = tree;
+ done();
+ });
+
+ xhr = FakeXhr.instances.pop();
+ xhr.respond(xml, 207);
+ });
+
+ test('simple tree', function() {
+ assert.ok(data.multistatus);
+ assert.ok(data.multistatus['/calendar/user/']);
+ });
+ });
+
+});