aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Lal <james@lightsofapollo.com>2012-06-27 11:31:51 +0200
committerJames Lal <james@lightsofapollo.com>2012-06-27 11:31:51 +0200
commitc3db57754c540129bd004137ab88be69788217d2 (patch)
tree758acbd7c7fcb42f392838a55125d090697a336c
parent95d50ef280c46ce6a29454285ccd7fc42cbcac61 (diff)
downloadjsCalDAV-c3db57754c540129bd004137ab88be69788217d2.tar.gz
Add calendar data / calendar query
-rw-r--r--lib/webcals/request/calendar_query.js31
-rw-r--r--lib/webcals/templates/calendar_data.js93
-rw-r--r--test/webcals/request/calendar_query_test.js104
-rw-r--r--test/webcals/templates/calendar_data_test.js65
4 files changed, 293 insertions, 0 deletions
diff --git a/lib/webcals/request/calendar_query.js b/lib/webcals/request/calendar_query.js
new file mode 100644
index 0000000..b25a1c1
--- /dev/null
+++ b/lib/webcals/request/calendar_query.js
@@ -0,0 +1,31 @@
+(function(module, ns) {
+
+ var Propfind = ns.require('request/propfind');
+
+ /**
+ * Creates a calendar query request.
+ *
+ * Defaults to Depth of 1.
+ *
+ * @param {String} url location to make request.
+ * @param {Object} options options for calendar query.
+ */
+ function CalendarQuery(url, options) {
+ Propfind.apply(this, arguments);
+
+ this.xhr.headers['Depth'] = this.depth || 1;
+ this.xhr.method = 'REPORT';
+ }
+
+ CalendarQuery.prototype = {
+ __proto__: Propfind.prototype
+ };
+
+ module.exports = CalendarQuery;
+
+}.apply(
+ this,
+ (this.Webcals) ?
+ [Webcals('request/calendar_query'), Webcals] :
+ [module, require('../webcals')]
+));
diff --git a/lib/webcals/templates/calendar_data.js b/lib/webcals/templates/calendar_data.js
new file mode 100644
index 0000000..9ff2a1e
--- /dev/null
+++ b/lib/webcals/templates/calendar_data.js
@@ -0,0 +1,93 @@
+(function(module, ns) {
+
+ function CalendarData() {
+ this.struct = {};
+ }
+
+ CalendarData.prototype = {
+
+ /**
+ * Appends a list of fields
+ * to a given iCalendar field set.
+ *
+ * @param {String} type iCal fieldset (VTODO, VEVENT,...).
+ */
+ select: function(type, list) {
+ var struct = this.struct;
+
+ if (!(type in struct)) {
+ struct[type] = [];
+ }
+
+ struct[type] = struct[type].concat(list);
+
+ return this;
+ },
+
+ /**
+ * Accepts an object full of arrays
+ * recuse when encountering another object.
+ */
+ _renderFieldset: function(template, element) {
+ var tag;
+ var value;
+ var i;
+ var output = '';
+ var elementOutput = '';
+
+ for (tag in element) {
+ value = element[tag];
+ for (i = 0; i < value.length; i++) {
+ if (typeof(value[i]) === 'object') {
+ elementOutput += this._renderFieldset(
+ template,
+ value[i]
+ );
+ } else {
+ elementOutput += template.tag(
+ ['caldav', 'prop'],
+ { name: value[i] }
+ );
+ }
+ }
+ output += template.tag(
+ ['caldav', 'comp'],
+ { name: tag },
+ elementOutput
+ );
+ elementOutput = '';
+ }
+
+ return output;
+ },
+
+ /**
+ * Renders CalendarData with a template.
+ *
+ * @param {WebCals.Template} template calendar to render.
+ * @return {String} <calendardata /> xml output.
+ */
+ render: function(template) {
+ var struct = this.struct;
+ var output = template.tag(
+ ['caldav', 'calendar-data'],
+ template.tag(
+ ['caldav', 'comp'],
+ { name: 'VCALENDAR' },
+ this._renderFieldset(template, struct)
+ )
+ );
+
+ return output;
+ }
+ };
+
+
+ module.exports = CalendarData;
+
+}.apply(
+ this,
+ (this.Webcals) ?
+ [Webcals('templates/calendar_data'), Webcals] :
+ [module, require('../webcals')]
+));
diff --git a/test/webcals/request/calendar_query_test.js b/test/webcals/request/calendar_query_test.js
new file mode 100644
index 0000000..803b09a
--- /dev/null
+++ b/test/webcals/request/calendar_query_test.js
@@ -0,0 +1,104 @@
+requireRequest();
+requireLib('request/propfind');
+requireLib('request/calendar_query');
+
+suite('webcals/request/propfind', function() {
+ var Abstract,
+ Propfind,
+ FakeXhr,
+ CalendarQuery,
+ Xhr,
+ Template,
+ oldXhrClass,
+ SaxResponse;
+
+ var url = 'http://google.com',
+ subject;
+
+ suiteSetup(function() {
+ Propfind = Webcals.require('request/propfind');
+ CalendarQuery = Webcals.require('request/calendar_query');
+ 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 CalendarQuery(url);
+ FakeXhr.instances.length = 0;
+ });
+
+ test('initializer', function() {
+ assert.instanceOf(subject, Propfind);
+ assert.deepEqual(subject._props, []);
+ assert.equal(subject.xhr.headers['Depth'], 1);
+ assert.equal(subject.xhr.method, 'REPORT');
+ });
+
+ test('#prop', function() {
+ var expected = subject.template.tag('test');
+
+ subject.prop('test');
+
+ assert.deepEqual(subject._props, [expected]);
+ });
+
+ test('#_createPayload', function() {
+ return;
+ 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('');
+
+ assert.equal(subject._createPayload(), expected);
+ });
+
+ suite('integration', function() {
+ return;
+ 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['/calendar/user/']);
+ });
+ });
+
+});
+
diff --git a/test/webcals/templates/calendar_data_test.js b/test/webcals/templates/calendar_data_test.js
new file mode 100644
index 0000000..5223f18
--- /dev/null
+++ b/test/webcals/templates/calendar_data_test.js
@@ -0,0 +1,65 @@
+requireRequest();
+requireLib('templates/calendar_data');
+
+suite('webcals/templates/calendar_data', function() {
+ var CalendarData;
+ var Template;
+
+ var subject;
+ var template;
+
+ function select() {
+ subject.select('VTODO', ['DTIME']);
+ subject.select('VTODO', ['NAME', { VTIMEZONE: true }]);
+ subject.select('VEVENT', ['NAME', {
+ 'VALARM': ['NAME']
+ }]);
+ }
+
+ suiteSetup(function() {
+ CalendarData = Webcals.require('templates/calendar_data');
+ Template = Webcals.require('template');
+ });
+
+ setup(function() {
+ subject = new CalendarData();
+ template = new Template('root');
+ });
+
+ test('initialization', function() {
+ assert.deepEqual(subject.struct, {});
+ });
+
+ suite('#render', function() {
+ var output;
+ var expected;
+
+ expected = [
+ '<N0:calendar-data>',
+ '<N0:comp name="VCALENDAR">',
+ '<N0:comp name="VTODO">',
+ '<N0:prop name="DTIME" />',
+ '<N0:prop name="NAME" />',
+ '<N0:comp name="VTIMEZONE" />',
+ '</N0:comp>',
+ '<N0:comp name="VEVENT">',
+ '<N0:prop name="NAME" />',
+ '<N0:comp name="VALARM">',
+ '<N0:prop name="NAME" />',
+ '</N0:comp>',
+ '</N0:comp>',
+ '</N0:comp>',
+ '</N0:calendar-data>'
+ ].join('');
+
+ setup(function() {
+ select();
+ });
+
+ test('output', function() {
+ var output = subject.render(template);
+ assert.equal(output, expected);
+ });
+ });
+
+});