diff options
-rw-r--r-- | lib/webcals/request/abstract.js | 12 | ||||
-rw-r--r-- | lib/webcals/request/propfind.js | 56 | ||||
-rw-r--r-- | test/webcals/request/abstract_test.js | 10 | ||||
-rw-r--r-- | test/webcals/request/propfind_test.js | 109 |
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/']); + }); + }); + +}); |