diff --git a/src/jio.storage/drivetojiomapping.js b/src/jio.storage/drivetojiomapping.js index 46ad242b179b915b29f90f8ec76502f20a86549e..91fbfafef15736c3cc3612248be66d695d82ed0f 100644 --- a/src/jio.storage/drivetojiomapping.js +++ b/src/jio.storage/drivetojiomapping.js @@ -1,6 +1,6 @@ -/*jslint nomen: true, maxlen: 200*/ -/*global console, RSVP, Blob*/ -(function (jIO) { +/*jslint nomen: true*/ +/*global RSVP, Blob*/ +(function (jIO, RSVP, Blob) { "use strict"; /** @@ -11,10 +11,11 @@ */ function FileSystemBridgeStorage(spec) { this._sub_storage = jIO.createJIO(spec.sub_storage); - this._document_key = "/.jio_documents/"; - this._attachment_key = "/.jio_attachments/"; } var DOCUMENT_EXTENSION = ".json", + DOCUMENT_REGEXP = new RegExp("^([\\w=]+)" + + DOCUMENT_EXTENSION + "$"), + DOCUMENT_KEY = "/.jio_documents/", ROOT = "/"; FileSystemBridgeStorage.prototype.get = function (param) { @@ -28,21 +29,22 @@ .push(function () { // First get the document itself if it exists return context._sub_storage.getAttachment({ - "_id": context._document_key, + "_id": DOCUMENT_KEY, "_attachment": param._id + DOCUMENT_EXTENSION }); }) .push(function (blob) { return new RSVP.Queue() .push(function () { - return jIO.util.readBlobAsText(blob); + return jIO.util.readBlobAsText(blob.data); }) .push(function (text) { explicit_document = true; return JSON.parse(text.target.result); }); }, function (error) { - if ((error instanceof jIO.util.jIOError) && (error.status_code === 404)) { + if ((error instanceof jIO.util.jIOError) && + (error.status_code === 404)) { return {}; } throw error; @@ -59,13 +61,15 @@ }) .push(function (directory_document) { - if (directory_document._attachments.hasOwnProperty(param._id)) { + if ((directory_document.hasOwnProperty("_attachments")) && + (directory_document._attachments.hasOwnProperty(param._id))) { json_document._attachments = { enclosure: {} }; } else { if (!explicit_document) { - throw new jIO.util.jIOError("Cannot find document", 404); + throw new jIO.util.jIOError("Cannot find document " + param._id, + 404); } } return json_document; @@ -73,38 +77,28 @@ }; - FileSystemBridgeStorage.prototype.post = function (param) { - var doc_id = param._id; - - if (doc_id === undefined) { - doc_id = jIO.util.generateUuid(); - } - - param._id = doc_id; - return this.put(param); - }; - FileSystemBridgeStorage.prototype.put = function (param) { var context = this, doc_id = param._id; // XXX Handle conflict! - // XXX Put empty enclosure directly if json is empty return context._sub_storage.putAttachment({ - "_id": context._document_key, + "_id": DOCUMENT_KEY, "_attachment": doc_id + DOCUMENT_EXTENSION, "_blob": new Blob([JSON.stringify(param)], {type: "application/json"}) }) .push(undefined, function (error) { - if ((error instanceof jIO.util.jIOError) && (error.status_code === 404)) { + if ((error instanceof jIO.util.jIOError) && + (error.status_code === 404)) { return context._sub_storage.put({ - "_id": context._document_key + "_id": DOCUMENT_KEY }) .push(function () { return context._sub_storage.putAttachment({ - "_id": context._document_key, + "_id": DOCUMENT_KEY, "_attachment": doc_id + DOCUMENT_EXTENSION, - "_blob": new Blob([JSON.stringify(param)], {type: "application/json"}) + "_blob": new Blob([JSON.stringify(param)], + {type: "application/json"}) }); }); } @@ -131,7 +125,8 @@ }) .push(undefined, function (error) { - if ((error instanceof jIO.util.jIOError) && (error.status_code === 404)) { + if ((error instanceof jIO.util.jIOError) && + (error.status_code === 404)) { got_error = true; return; } @@ -141,14 +136,15 @@ // Second, try to remove explicit doc .push(function () { return context._sub_storage.removeAttachment({ - "_id": context._document_key, + "_id": DOCUMENT_KEY, "_attachment": doc_id + DOCUMENT_EXTENSION }); }) .push(undefined, function (error) { - if ((!got_error) && (error instanceof jIO.util.jIOError) && (error.status_code === 404)) { - return; + if ((!got_error) && (error instanceof jIO.util.jIOError) && + (error.status_code === 404)) { + return doc_id; } throw error; }); @@ -156,10 +152,7 @@ }; FileSystemBridgeStorage.prototype.hasCapacity = function (capacity) { - if (capacity === "list") { - return true; - } - return false; + return (capacity === "list"); }; FileSystemBridgeStorage.prototype.buildQuery = function () { @@ -171,18 +164,21 @@ .push(function () { return context._sub_storage.get({ - "_id": context._document_key + "_id": DOCUMENT_KEY }); }) .push(function (result) { var key; for (key in result._attachments) { if (result._attachments.hasOwnProperty(key)) { - result_dict[key.slice(0, key.length - DOCUMENT_EXTENSION.length)] = null; + if (DOCUMENT_REGEXP.test(key)) { + result_dict[DOCUMENT_REGEXP.exec(key)[1]] = null; + } } } }, function (error) { - if ((error instanceof jIO.util.jIOError) && (error.status_code === 404)) { + if ((error instanceof jIO.util.jIOError) && + (error.status_code === 404)) { return; } throw error; @@ -224,7 +220,8 @@ FileSystemBridgeStorage.prototype.getAttachment = function (param) { if (param._attachment !== "enclosure") { - throw new Error("Only support 'enclosure' attachment"); + throw new jIO.util.jIOError("Only support 'enclosure' attachment", + 400); } return this._sub_storage.getAttachment({ @@ -235,7 +232,8 @@ FileSystemBridgeStorage.prototype.putAttachment = function (param) { if (param._attachment !== "enclosure") { - throw new Error("Only support 'enclosure' attachment"); + throw new jIO.util.jIOError("Only support 'enclosure' attachment", + 400); } return this._sub_storage.putAttachment({ @@ -247,7 +245,8 @@ FileSystemBridgeStorage.prototype.removeAttachment = function (param) { if (param._attachment !== "enclosure") { - throw new Error("Only support 'enclosure' attachment"); + throw new jIO.util.jIOError("Only support 'enclosure' attachment", + 400); } return this._sub_storage.removeAttachment({ @@ -258,4 +257,4 @@ jIO.addStorage('drivetojiomapping', FileSystemBridgeStorage); -}(jIO)); +}(jIO, RSVP, Blob)); diff --git a/test/jio.storage/drivetojiomapping.tests.js b/test/jio.storage/drivetojiomapping.tests.js new file mode 100644 index 0000000000000000000000000000000000000000..518b6a4cd4c0b8473c7aec525e29789f749b571d --- /dev/null +++ b/test/jio.storage/drivetojiomapping.tests.js @@ -0,0 +1,1061 @@ +/*jslint nomen: true*/ +/*global Blob*/ +(function (jIO, QUnit, Blob) { + "use strict"; + var test = QUnit.test, + stop = QUnit.stop, + start = QUnit.start, + ok = QUnit.ok, + expect = QUnit.expect, + deepEqual = QUnit.deepEqual, + equal = QUnit.equal, + module = QUnit.module; + + ///////////////////////////////////////////////////////////////// + // Custom test substorage definition + ///////////////////////////////////////////////////////////////// + function Storage200() { + return this; + } + jIO.addStorage('drivetojiomapping200', Storage200); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.constructor + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.constructor"); + test("create substorage", function () { + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }); + + ok(jio.__storage._sub_storage instanceof jio.constructor); + equal(jio.__storage._sub_storage.__type, "drivetojiomapping200"); + + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.get + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.get"); + + test("get non existent document", function () { + stop(); + expect(5); + + function StorageGetNoDocument() { + return this; + } + StorageGetNoDocument.prototype.getAttachment = function (options) { + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "getAttachment"); + throw new jIO.util.jIOError("Cannot find subattachment", 404); + }; + StorageGetNoDocument.prototype.get = function (options) { + deepEqual(options, {"_id": "/"}, "Get document"); + return { + "_id": "/" + }; + }; + + jIO.addStorage('drivetojiomappinggetnodocument', StorageGetNoDocument); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappinggetnodocument" + } + }); + + jio.get({"_id": "bar"}) + .then(function () { + ok(false); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Cannot find document bar"); + equal(error.status_code, 404); + }) + .always(function () { + start(); + }); + }); + + test("get document with only one attachment", function () { + stop(); + expect(3); + + function StorageGetOnlyAttachment() { + return this; + } + StorageGetOnlyAttachment.prototype.getAttachment = function (options) { + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "getAttachment"); + throw new jIO.util.jIOError("Cannot find subattachment", 404); + }; + StorageGetOnlyAttachment.prototype.get = function (options) { + deepEqual(options, {"_id": "/"}, "Get document"); + return { + "_id": "/", + "_attachments": { + "bar": {} + } + }; + }; + + jIO.addStorage('drivetojiomappinggetonlyattachment', + StorageGetOnlyAttachment); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappinggetonlyattachment" + } + }); + + jio.get({"_id": "bar"}) + .then(function (result) { + deepEqual(result, { + "_id": "bar", + "_attachments": { + enclosure: {} + } + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("get document with only one document", function () { + stop(); + expect(3); + + function StorageGetOnlyDocument() { + return this; + } + StorageGetOnlyDocument.prototype.getAttachment = function (options) { + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "getAttachment"); + return {data: new Blob([JSON.stringify({title: "foo"})])}; + }; + StorageGetOnlyDocument.prototype.get = function (options) { + deepEqual(options, {"_id": "/"}, "Get document"); + return { + "_id": "/" + }; + }; + + jIO.addStorage('drivetojiomappinggetonlydocument', StorageGetOnlyDocument); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappinggetonlydocument" + } + }); + + jio.get({"_id": "bar"}) + .then(function (result) { + deepEqual(result, { + "_id": "bar", + "title": "foo" + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("get document with one document and one attachment", function () { + stop(); + expect(3); + + function StorageGetBoth() { + return this; + } + StorageGetBoth.prototype.getAttachment = function (options) { + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "getAttachment"); + return {data: new Blob([JSON.stringify({title: "foo"})])}; + }; + StorageGetBoth.prototype.get = function (options) { + deepEqual(options, {"_id": "/"}, "Get document"); + return { + "_id": "/", + "_attachments": { + "bar": {} + } + }; + }; + + jIO.addStorage('drivetojiomappinggetboth', StorageGetBoth); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappinggetboth" + } + }); + + jio.get({"_id": "bar"}) + .then(function (result) { + deepEqual(result, { + "_id": "bar", + "title": "foo", + "_attachments": { + enclosure: {} + } + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.put + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.put"); + test("put called substorage put", function () { + stop(); + expect(4); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }); + Storage200.prototype.putAttachment = function (param) { + var blob = param._blob; + delete param._blob; + equal(blob.type, "application/json", "Blob type is OK"); + deepEqual(param, { + "_id": "/.jio_documents/", + "_attachment": "bar.json" + }, "putAttachment 200 called"); + + return jIO.util.readBlobAsText(blob) + .then(function (result) { + deepEqual(JSON.parse(result.target.result), + {"_id": "bar", "title": "bartitle"}, + "JSON is in blob"); + return param._id; + }); + + }; + + jio.put({"_id": "bar", "title": "bartitle"}) + .then(function (result) { + equal(result, "bar"); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("automatically create subdocuments", function () { + stop(); + expect(8); + + var call_count = 0, + jio; + + function StorageCreateSubDocument() { + return this; + } + StorageCreateSubDocument.prototype.putAttachment = function (param) { + call_count += 1; + var blob = param._blob; + delete param._blob; + equal(blob.type, "application/json", "Blob type is OK"); + deepEqual(param, { + "_id": "/.jio_documents/", + "_attachment": "bar.json" + }, "putAttachment 200 called"); + + return jIO.util.readBlobAsText(blob) + .then(function (result) { + deepEqual(JSON.parse(result.target.result), + {"_id": "bar", "title": "bartitle"}, + "JSON is in blob"); + if (call_count === 1) { + throw new jIO.util.jIOError("Cannot access subdocument", 404); + } + return "PutSubAttachment OK"; + }); + }; + + StorageCreateSubDocument.prototype.put = function (param) { + deepEqual(param, { + "_id": "/.jio_documents/" + }, "put 200 called"); + return "PutSubDocument OK"; + }; + + jIO.addStorage('drivetojiomappingcreatesubdocument', + StorageCreateSubDocument); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingcreatesubdocument" + } + }); + + jio.put({"_id": "bar", "title": "bartitle"}) + .then(function (result) { + equal(result, "bar"); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.remove + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.remove"); + + test("remove non existent document", function () { + var call_count = 0, + jio; + stop(); + expect(6); + + function StorageRemoveNoDocument() { + return this; + } + StorageRemoveNoDocument.prototype.removeAttachment = function (options) { + call_count += 1; + if (call_count === 1) { + deepEqual(options, {"_id": "/", + "_attachment": "bar"}, + "removeAttachment"); + throw new jIO.util.jIOError("Cannot find subattachment", 404); + } + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "removeAttachment"); + throw new jIO.util.jIOError("Cannot find subdocument", 404); + }; + + jIO.addStorage('drivetojiomappingremovenodocument', + StorageRemoveNoDocument); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingremovenodocument" + } + }); + + jio.remove({"_id": "bar"}) + .then(function () { + ok(false); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Cannot find subdocument"); + equal(error.status_code, 404); + }) + .then(function () { + equal(call_count, 2); + }) + .always(function () { + start(); + }); + }); + + test("remove document with only one attachment", function () { + var call_count = 0, + jio; + stop(); + expect(4); + + function StorageRemoveOnlyAttachment() { + return this; + } + StorageRemoveOnlyAttachment.prototype.removeAttachment = + function (options) { + call_count += 1; + if (call_count === 1) { + deepEqual(options, {"_id": "/", + "_attachment": "bar"}, + "removeAttachment"); + return "Removed"; + } + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "removeAttachment"); + throw new jIO.util.jIOError("Cannot find subdocument", 404); + }; + + jIO.addStorage('drivetojiomappingremoveonlyattachment', + StorageRemoveOnlyAttachment); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingremoveonlyattachment" + } + }); + + jio.remove({"_id": "bar"}) + .then(function (result) { + equal(result, "bar"); + equal(call_count, 2); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("remove document with only one document", function () { + var call_count = 0, + jio; + stop(); + expect(4); + + function StorageRemoveOnlyDocument() { + return this; + } + StorageRemoveOnlyDocument.prototype.removeAttachment = function (options) { + call_count += 1; + if (call_count === 1) { + deepEqual(options, {"_id": "/", + "_attachment": "bar"}, + "removeAttachment"); + throw new jIO.util.jIOError("Cannot find subattachment", 404); + } + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "removeAttachment"); + return "Removed"; + }; + + jIO.addStorage('drivetojiomappingremoveonlydocument', + StorageRemoveOnlyDocument); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingremoveonlydocument" + } + }); + + jio.remove({"_id": "bar"}) + .then(function (result) { + equal(result, "Removed"); + equal(call_count, 2); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("remove document with one document and one attachment", function () { + var call_count = 0, + jio; + stop(); + expect(4); + + function StorageRemoveBoth() { + return this; + } + StorageRemoveBoth.prototype.removeAttachment = function (options) { + call_count += 1; + if (call_count === 1) { + deepEqual(options, {"_id": "/", + "_attachment": "bar"}, + "removeAttachment"); + return "Removed attachment"; + } + deepEqual(options, {"_id": "/.jio_documents/", + "_attachment": "bar.json"}, + "removeAttachment"); + return "Removed document"; + }; + + jIO.addStorage('drivetojiomappingremoveboth', StorageRemoveBoth); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingremoveboth" + } + }); + + jio.remove({"_id": "bar"}) + .then(function (result) { + equal(result, "Removed document"); + equal(call_count, 2); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.getAttachment + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.getAttachment"); + test("reject non enclosure attachment", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }); + + jio.getAttachment({"_id": "bar", "_attachment": "foo"}) + .then(function () { + ok(false); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Only support 'enclosure' attachment"); + equal(error.status_code, 400); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("getAttachment called substorage getAttachment", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }), + blob = new Blob(["foo"]); + + Storage200.prototype.getAttachment = function (param) { + deepEqual(param, {"_id": "/", + "_attachment": "bar"}, + "getAttachment 200 called"); + return {data: blob}; + }; + + jio.getAttachment({"_id": "bar", "_attachment": "enclosure"}) + .then(function (result) { + equal(result.data, blob); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.putAttachment + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.putAttachment"); + test("reject non enclosure attachment", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }); + + jio.putAttachment({"_id": "bar", "_attachment": "foo", + "_blob": new Blob(["foo"])}) + .then(function () { + ok(false); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Only support 'enclosure' attachment"); + equal(error.status_code, 400); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("putAttachment called substorage putAttachment", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }), + blob = new Blob(["foo"]); + + Storage200.prototype.putAttachment = function (param) { + deepEqual(param, {"_id": "/", + "_blob": blob, + "_attachment": "bar"}, + "putAttachment 200 called"); + return "Put"; + }; + + jio.putAttachment({"_id": "bar", "_attachment": "enclosure", "_blob": blob}) + .then(function (result) { + equal(result, "Put"); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.removeAttachment + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.removeAttachment"); + test("reject non enclosure attachment", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }); + + jio.removeAttachment({"_id": "bar", "_attachment": "foo"}) + .then(function () { + ok(false); + }) + .fail(function (error) { + ok(error instanceof jIO.util.jIOError); + equal(error.message, "Only support 'enclosure' attachment"); + equal(error.status_code, 400); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("removeAttachment called substorage removeAttachment", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }); + + Storage200.prototype.removeAttachment = function (param) { + deepEqual(param, {"_id": "/", + "_attachment": "bar"}, + "removeAttachment 200 called"); + return "Removed"; + }; + + jio.removeAttachment({"_id": "bar", "_attachment": "enclosure"}) + .then(function (result) { + equal(result, "Removed"); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.hasCapacity + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.hasCapacity"); + test("can list documents", function () { + var jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomapping200" + } + }); + + ok(jio.hasCapacity("list")); + }); + + ///////////////////////////////////////////////////////////////// + // driveToJioMapping.buildQuery + ///////////////////////////////////////////////////////////////// + module("driveToJioMapping.buildQuery"); + + test("no document directory, no attachments: empty result", function () { + stop(); + expect(3); + + var call_count = 0, + jio; + + function StorageAllDocsNoDirectory() { + return this; + } + + StorageAllDocsNoDirectory.prototype.get = function (param) { + call_count += 1; + if (call_count === 1) { + deepEqual(param, { + "_id": "/.jio_documents/" + }, "get documents called"); + throw new jIO.util.jIOError("Cannot access subdocument", 404); + } + + deepEqual(param, { + "_id": "/" + }, "get attachments called"); + return { + "_id": "/" + }; + }; + + jIO.addStorage('drivetojiomappingalldocsnodirectory', + StorageAllDocsNoDirectory); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingalldocsnodirectory" + } + }); + + jio.allDocs() + .then(function (result) { + deepEqual(result, { + data: { + rows: [], + total_rows: 0 + } + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("empty document directory, no attachments: empty result", function () { + stop(); + expect(3); + + var call_count = 0, + jio; + + function StorageAllDocsEmpty() { + return this; + } + + StorageAllDocsEmpty.prototype.get = function (param) { + call_count += 1; + if (call_count === 1) { + deepEqual(param, { + "_id": "/.jio_documents/" + }, "get documents called"); + return { + "_id": "/.jio_documents/" + }; + } + + deepEqual(param, { + "_id": "/" + }, "get attachments called"); + return { + "_id": "/" + }; + }; + + jIO.addStorage('drivetojiomappingalldocsempty', + StorageAllDocsEmpty); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingalldocsempty" + } + }); + + jio.allDocs() + .then(function (result) { + deepEqual(result, { + data: { + rows: [], + total_rows: 0 + } + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("no document directory, attachments found: attachments as result", + function () { + stop(); + expect(3); + + var call_count = 0, + jio; + + function StorageAllDocsAttachmentsOnly() { + return this; + } + + StorageAllDocsAttachmentsOnly.prototype.get = function (param) { + call_count += 1; + if (call_count === 1) { + deepEqual(param, { + "_id": "/.jio_documents/" + }, "get documents called"); + throw new jIO.util.jIOError("Cannot access subdocument", 404); + } + + deepEqual(param, { + "_id": "/" + }, "get attachments called"); + return { + "_id": "/", + "_attachments": { + foo: {}, + bar: {} + } + }; + }; + + jIO.addStorage('drivetojiomappingalldocsattachmentsonly', + StorageAllDocsAttachmentsOnly); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingalldocsattachmentsonly" + } + }); + + jio.allDocs() + .then(function (result) { + deepEqual(result, { + data: { + rows: [{ + id: "foo", + value: {} + }, { + id: "bar", + value: {} + }], + total_rows: 2 + } + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("document directory, no attachments: json document as result", + function () { + stop(); + expect(3); + + var call_count = 0, + jio; + + function StorageAllDocsFilterDocument() { + return this; + } + + StorageAllDocsFilterDocument.prototype.get = function (param) { + call_count += 1; + if (call_count === 1) { + deepEqual(param, { + "_id": "/.jio_documents/" + }, "get documents called"); + return { + "_id": "/", + "_attachments": { + "foo.json": {}, + "bar.json": {}, + "foobar.pasjson": {} + } + }; + } + + deepEqual(param, { + "_id": "/" + }, "get attachments called"); + return { + "_id": "/" + }; + }; + + jIO.addStorage('drivetojiomappingalldocsfilterdocument', + StorageAllDocsFilterDocument); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingalldocsfilterdocument" + } + }); + + jio.allDocs() + .then(function (result) { + deepEqual(result, { + data: { + rows: [{ + id: "foo", + value: {} + }, { + id: "bar", + value: {} + }], + total_rows: 2 + } + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("document directory, attachments found: merge result", function () { + stop(); + expect(3); + + var call_count = 0, + jio; + + function StorageAllDocsBoth() { + return this; + } + + StorageAllDocsBoth.prototype.get = function (param) { + call_count += 1; + if (call_count === 1) { + deepEqual(param, { + "_id": "/.jio_documents/" + }, "get documents called"); + return { + "_id": "/", + "_attachments": { + "foo.json": {}, + "bar.json": {} + } + }; + } + + deepEqual(param, { + "_id": "/" + }, "get attachments called"); + return { + "_id": "/", + "_attachments": { + "bar": {}, + "foobar": {} + } + }; + }; + + jIO.addStorage('drivetojiomappingalldocsboth', + StorageAllDocsBoth); + + jio = jIO.createJIO({ + type: "drivetojiomapping", + sub_storage: { + type: "drivetojiomappingalldocsboth" + } + }); + + jio.allDocs() + .then(function (result) { + deepEqual(result, { + data: { + rows: [{ + id: "foo", + value: {} + }, { + id: "bar", + value: {} + }, { + id: "foobar", + value: {} + }], + total_rows: 3 + } + }); + }) + .fail(function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + +}(jIO, QUnit, Blob)); diff --git a/test/tests.html b/test/tests.html index 9fa660cb908c3a90dda4e32645a874c123b4d882..3607480e3f20fbaccdb2e5a97d4f2498fd17cd60 100644 --- a/test/tests.html +++ b/test/tests.html @@ -30,6 +30,7 @@ <script src="jio.storage/localstorage.tests.js"></script> <script src="jio.storage/documentstorage.tests.js"></script> <script src="jio.storage/davstorage.tests.js"></script> + <script src="jio.storage/drivetojiomapping.tests.js"></script> <!--script src="jio.storage/unionstorage.tests.js"></script-->