diff --git a/src/jio.storage/mappingstorage.js b/src/jio.storage/mappingstorage.js new file mode 100644 index 0000000000000000000000000000000000000000..ad4742bd4549f0cf099098ac99b0a180963b8532 --- /dev/null +++ b/src/jio.storage/mappingstorage.js @@ -0,0 +1,656 @@ +/*jslint indent:2, maxlen: 80, nomen: true */ +/*global jIO, RSVP, UriTemplate, SimpleQuery, ComplexQuery, QueryFactory, + Query, FormData*/ +(function (jIO, RSVP, UriTemplate, SimpleQuery, ComplexQuery, QueryFactory, + Query, FormData) { + "use strict"; + + function getSubIdEqualSubProperty(storage, value, key) { + var query; + if (storage._no_sub_query_id) { + throw new jIO.util.jIOError('no sub query id active', 404); + } + if (!value) { + throw new jIO.util.jIOError( + 'can not find document with ' + key + ' : undefined', + 404 + ); + } + if (storage._mapping_id_memory_dict[value]) { + return storage._mapping_id_memory_dict[value]; + } + query = new SimpleQuery({ + key: key, + value: value, + type: "simple" + }); + if (storage._query.query !== undefined) { + query = new ComplexQuery({ + operator: "AND", + query_list: [query, storage._query.query], + type: "complex" + }); + } + query = Query.objectToSearchText(query); + return storage._sub_storage.allDocs({ + "query": query, + "sort_on": storage._query.sort_on, + "select_list": storage._query.select_list, + "limit": storage._query.limit + }) + .push(function (data) { + if (data.data.total_rows === 0) { + throw new jIO.util.jIOError( + "Can not find document with (" + key + ", " + value + ")", + 404 + ); + } + if (data.data.total_rows > 1) { + throw new TypeError("id must be unique field: " + key + + ", result:" + data.data.rows.toString()); + } + storage._mapping_id_memory_dict[value] = data.data.rows[0].id; + return data.data.rows[0].id; + }); + } + + /*jslint unparam: true*/ + var mapping_function = { + "equalSubProperty": { + "mapToSubProperty": function (property, sub_doc, doc, args, id) { + sub_doc[args] = doc[property]; + return args; + }, + "mapToMainProperty": function (property, sub_doc, doc, args, sub_id) { + if (sub_doc.hasOwnProperty(args)) { + doc[property] = sub_doc[args]; + } + return args; + }, + "mapToSubId": function (storage, doc, id, args) { + if (doc !== undefined) { + if (storage._property_for_sub_id && + doc.hasOwnProperty(storage._property_for_sub_id)) { + return doc[storage._property_for_sub_id]; + } + } + return getSubIdEqualSubProperty(storage, id, storage._map_id[1]); + }, + "mapToId": function (storage, sub_doc, sub_id, args) { + return sub_doc[args]; + } + }, + "equalValue": { + "mapToSubProperty": function (property, sub_doc, doc, args) { + sub_doc[property] = args; + return property; + }, + "mapToMainProperty": function (property) { + return property; + } + }, + "ignore": { + "mapToSubProperty": function () { + return false; + }, + "mapToMainProperty": function (property) { + return property; + } + }, + "equalSubId": { + "mapToSubProperty": function (property, sub_doc, doc) { + sub_doc[property] = doc[property]; + return property; + }, + "mapToMainProperty": function (property, sub_doc, doc, args, sub_id) { + if (sub_id === undefined && sub_doc.hasOwnProperty(property)) { + doc[property] = sub_doc[property]; + } else { + doc[property] = sub_id; + } + return property; + }, + "mapToSubId": function (storage, doc, id, args) { + return id; + }, + "mapToId": function (storage, sub_doc, sub_id) { + return sub_id; + } + }, + "keep": { + "mapToSubProperty": function (property, sub_doc, doc) { + sub_doc[property] = doc[property]; + return property; + }, + "mapToMainProperty": function (property, sub_doc, doc) { + doc[property] = sub_doc[property]; + return property; + } + }, + "switchPropertyValue": { + "mapToSubProperty": function (property, sub_doc, doc, args) { + sub_doc[args[0]] = args[1][doc[property]]; + return args[0]; + }, + "mapToMainProperty": function (property, sub_doc, doc, args) { + var subvalue, value = sub_doc[args[0]]; + for (subvalue in args[1]) { + if (args[1].hasOwnProperty(subvalue)) { + if (value === args[1][subvalue]) { + doc[property] = subvalue; + return property; + } + } + } + } + } + }; + /*jslint unparam: false*/ + + function initializeQueryAndDefaultMapping(storage) { + var property, query_list = []; + for (property in storage._mapping_dict) { + if (storage._mapping_dict.hasOwnProperty(property)) { + if (storage._mapping_dict[property][0] === "equalValue") { + if (storage._mapping_dict[property][1] === undefined) { + throw new jIO.util.jIOError("equalValue has not parameter", 400); + } + storage._default_mapping[property] = + storage._mapping_dict[property][1]; + query_list.push(new SimpleQuery({ + key: property, + value: storage._mapping_dict[property][1], + type: "simple" + })); + } + if (storage._mapping_dict[property][0] === "equalSubId") { + if (storage._property_for_sub_id !== undefined) { + throw new jIO.util.jIOError( + "equalSubId can be defined one time", + 400 + ); + } + storage._property_for_sub_id = property; + } + } + } + if (storage._map_id[0] === "equalSubProperty") { + storage._mapping_dict[storage._map_id[1]] = ["keep"]; + } + if (storage._query.query !== undefined) { + query_list.push(QueryFactory.create(storage._query.query)); + } + if (query_list.length > 1) { + storage._query.query = new ComplexQuery({ + type: "complex", + query_list: query_list, + operator: "AND" + }); + } else if (query_list.length === 1) { + storage._query.query = query_list[0]; + } + } + + function MappingStorage(spec) { + this._mapping_dict = spec.property || {}; + this._sub_storage = jIO.createJIO(spec.sub_storage); + this._map_all_property = spec.map_all_property !== undefined ? + spec.map_all_property : true; + this._no_sub_query_id = spec.no_sub_query_id; + this._attachment_mapping_dict = spec.attachment || {}; + this._query = spec.query || {}; + this._map_id = spec.id || ["equalSubId"]; + this._id_mapped = (spec.id !== undefined) ? spec.id[1] : false; + + if (this._query.query !== undefined) { + this._query.query = QueryFactory.create(this._query.query); + } + this._default_mapping = {}; + this._mapping_id_memory_dict = {}; + this._attachment_list = spec.attachment_list || []; + this._caching_dict = {id: {}}; + + initializeQueryAndDefaultMapping(this); + } + + function getAttachmentId(storage, sub_id, attachment_id, method) { + var mapping_dict = storage._attachment_mapping_dict; + if (mapping_dict !== undefined + && mapping_dict[attachment_id] !== undefined + && mapping_dict[attachment_id][method] !== undefined + && mapping_dict[attachment_id][method].uri_template !== undefined) { + return UriTemplate.parse( + mapping_dict[attachment_id][method].uri_template + ).expand({id: sub_id}); + } + return attachment_id; + } + + function getSubStorageId(storage, id, doc) { + if (storage._caching_dict.id.hasOwnProperty(id)) { + return new RSVP.Queue() + .push(function () { + return storage._caching_dict.id[id]; + }); + } + return new RSVP.Queue() + .push(function () { + var map_info = storage._map_id || ["equalSubId"]; + if (storage._property_for_sub_id && doc !== undefined && + doc.hasOwnProperty(storage._property_for_sub_id)) { + return doc[storage._property_for_sub_id]; + } + return mapping_function[map_info[0]].mapToSubId( + storage, + doc, + id, + map_info[1] + ); + }) + .push(function (sub_id) { + storage._caching_dict.id[id] = sub_id; + return sub_id; + }); + } + + function mapToSubProperty(storage, property, sub_doc, doc, id) { + var mapping_info = storage._mapping_dict[property] || ["keep"]; + return mapping_function[mapping_info[0]].mapToSubProperty( + property, + sub_doc, + doc, + mapping_info[1], + id + ); + } + + function mapToMainProperty(storage, property, sub_doc, doc, sub_id) { + var mapping_info = storage._mapping_dict[property] || ["keep"]; + return mapping_function[mapping_info[0]].mapToMainProperty( + property, + sub_doc, + doc, + mapping_info[1], + sub_id + ); + } + + function mapToMainDocument(storage, sub_doc, sub_id) { + var doc = {}, + property, + property_list = [storage._id_mapped]; + for (property in storage._mapping_dict) { + if (storage._mapping_dict.hasOwnProperty(property)) { + property_list.push(mapToMainProperty( + storage, + property, + sub_doc, + doc, + sub_id + )); + } + } + if (storage._map_all_property) { + for (property in sub_doc) { + if (sub_doc.hasOwnProperty(property)) { + if (property_list.indexOf(property) < 0) { + doc[property] = sub_doc[property]; + } + } + } + } + if (storage._map_for_sub_storage_id !== undefined) { + doc[storage._map_for_sub_storage_id] = sub_id; + } + return doc; + } + + function mapToSubstorageDocument(storage, doc, id) { + var sub_doc = {}, property; + + for (property in doc) { + if (doc.hasOwnProperty(property)) { + mapToSubProperty(storage, property, sub_doc, doc, id); + } + } + for (property in storage._default_mapping) { + if (storage._default_mapping.hasOwnProperty(property)) { + sub_doc[property] = storage._default_mapping[property]; + } + } + if (storage._map_id[0] === "equalSubProperty" && id !== undefined) { + sub_doc[storage._map_id[1]] = id; + } + return sub_doc; + } + + function handleAttachment(storage, argument_list, method) { + return getSubStorageId(storage, argument_list[0]) + .push(function (sub_id) { + argument_list[0] = sub_id; + var old_id = argument_list[1]; + argument_list[1] = getAttachmentId( + storage, + argument_list[0], + argument_list[1], + method + ); + if (storage._attachment_list.length > 0 + && storage._attachment_list.indexOf(old_id) < 0) { + if (method === "get") { + throw new jIO.util.jIOError("unhautorized attachment", 404); + } + return; + } + return storage._sub_storage[method + "Attachment"].apply( + storage._sub_storage, + argument_list + ); + }); + } + + MappingStorage.prototype.get = function (id) { + var storage = this; + return getSubStorageId(this, id) + .push(function (sub_id) { + return storage._sub_storage.get(sub_id) + .push(function (sub_doc) { + return mapToMainDocument(storage, sub_doc, sub_id); + }); + }); + }; + + MappingStorage.prototype.post = function (doc) { + var sub_doc = mapToSubstorageDocument( + this, + doc + ), + id = doc[this._property_for_sub_id], + storage = this; + if (this._property_for_sub_id && id !== undefined) { + return this._sub_storage.put(id, sub_doc); + } + if (this._id_mapped && doc[this._id_mapped] !== undefined) { + return getSubStorageId(storage, id, doc) + .push(function (sub_id) { + return storage._sub_storage.put(sub_id, sub_doc); + }) + .push(function () { + return doc[storage._id_mapped]; + }) + .push(undefined, function (error) { + if (error instanceof jIO.util.jIOError) { + return storage._sub_storage.post(sub_doc); + } + throw error; + }); + } + throw new jIO.util.jIOError( + "post is not supported with id mapped", + 400 + ); + }; + + MappingStorage.prototype.put = function (id, doc) { + var storage = this, + sub_doc = mapToSubstorageDocument(this, doc, id); + return getSubStorageId(this, id, doc) + .push(function (sub_id) { + return storage._sub_storage.put(sub_id, sub_doc); + }) + .push(undefined, function (error) { + if (error instanceof jIO.util.jIOError && error.status_code === 404) { + return storage._sub_storage.post(sub_doc); + } + throw error; + }) + .push(function () { + return id; + }); + }; + + MappingStorage.prototype.remove = function (id) { + var storage = this; + return getSubStorageId(this, id) + .push(function (sub_id) { + return storage._sub_storage.remove(sub_id); + }) + .push(function () { + return id; + }); + }; + + MappingStorage.prototype.getAttachment = function () { + return handleAttachment(this, arguments, "get"); + }; + + MappingStorage.prototype.putAttachment = function (id, attachment_id, blob) { + var storage = this, + mapping_dict = storage._attachment_mapping_dict; + // THIS IS REALLY BAD, FIND AN OTHER WAY IN FUTURE + if (mapping_dict !== undefined + && mapping_dict[attachment_id] !== undefined + && mapping_dict[attachment_id].put !== undefined + && mapping_dict[attachment_id].put.erp5_put_template !== undefined) { + return getSubStorageId(storage, id) + .push(function (sub_id) { + var url = UriTemplate.parse( + mapping_dict[attachment_id].put.erp5_put_template + ).expand({id: sub_id}), + data = new FormData(); + data.append("field_my_file", blob); + data.append("form_id", "File_view"); + return jIO.util.ajax({ + "type": "POST", + "url": url, + "data": data, + "xhrFields": { + withCredentials: true + } + }); + }); + } + return handleAttachment(this, arguments, "put", id) + .push(function () { + return attachment_id; + }); + }; + + MappingStorage.prototype.removeAttachment = function (id, attachment_id) { + return handleAttachment(this, arguments, "remove", id) + .push(function () { + return attachment_id; + }); + }; + + MappingStorage.prototype.allAttachments = function (id) { + var storage = this, sub_id; + return getSubStorageId(storage, id) + .push(function (sub_id_result) { + sub_id = sub_id_result; + return storage._sub_storage.allAttachments(sub_id); + }) + .push(function (result) { + var attachment_id, + attachments = {}, + mapping_dict = {}, + i; + for (attachment_id in storage._attachment_mapping_dict) { + if (storage._attachment_mapping_dict.hasOwnProperty(attachment_id)) { + mapping_dict[getAttachmentId(storage, sub_id, attachment_id, "get")] + = attachment_id; + } + } + for (attachment_id in result) { + if (result.hasOwnProperty(attachment_id)) { + if (!(storage._attachment_list.length > 0 + && storage._attachment_list.indexOf(attachment_id) < 0)) { + if (mapping_dict.hasOwnProperty(attachment_id)) { + attachments[mapping_dict[attachment_id]] = {}; + } else { + attachments[attachment_id] = {}; + } + } + } + } + for (i = 0; i < storage._attachment_list.length; i += 1) { + if (!attachments.hasOwnProperty(storage._attachment_list[i])) { + attachments[storage._attachment_list[i]] = {}; + } + } + return attachments; + }); + }; + + MappingStorage.prototype.hasCapacity = function (name) { + return this._sub_storage.hasCapacity(name); + }; + + MappingStorage.prototype.repair = function () { + return this._sub_storage.repair.apply(this._sub_storage, arguments); + }; + + MappingStorage.prototype.bulk = function (id_list) { + var storage = this; + + function mapId(parameter) { + return getSubStorageId(storage, parameter.parameter_list[0]) + .push(function (id) { + return {"method": parameter.method, "parameter_list": [id]}; + }); + } + + return new RSVP.Queue() + .push(function () { + var promise_list = id_list.map(mapId); + return RSVP.all(promise_list); + }) + .push(function (id_list_mapped) { + return storage._sub_storage.bulk(id_list_mapped); + }) + .push(function (result) { + var mapped_result = [], i; + for (i = 0; i < result.length; i += 1) { + mapped_result.push(mapToMainDocument( + storage, + result[i] + )); + } + return mapped_result; + }); + }; + + MappingStorage.prototype.buildQuery = function (option) { + var storage = this, + i, + query, + property, + select_list = [], + sort_on = []; + + function mapQuery(one_query) { + var j, query_list = [], key, sub_query; + if (one_query.type === "complex") { + for (j = 0; j < one_query.query_list.length; j += 1) { + sub_query = mapQuery(one_query.query_list[j]); + if (sub_query) { + query_list.push(sub_query); + } + } + one_query.query_list = query_list; + return one_query; + } + key = mapToMainProperty(storage, one_query.key, {}, {}); + if (key !== undefined) { + one_query.key = key; + return one_query; + } + return false; + } + + if (option.sort_on !== undefined) { + for (i = 0; i < option.sort_on.length; i += 1) { + property = mapToMainProperty(this, option.sort_on[i][0], {}, {}); + if (property && sort_on.indexOf(property) < 0) { + sort_on.push([property, option.sort_on[i][1]]); + } + } + } + if (this._query.sort_on !== undefined) { + for (i = 0; i < this._query.sort_on.length; i += 1) { + property = mapToMainProperty(this, this._query.sort_on[i], {}, {}); + if (sort_on.indexOf(property) < 0) { + sort_on.push([property, option.sort_on[i][1]]); + } + } + } + if (option.select_list !== undefined) { + for (i = 0; i < option.select_list.length; i += 1) { + property = mapToMainProperty(this, option.select_list[i], {}, {}); + if (property && select_list.indexOf(property) < 0) { + select_list.push(property); + } + } + } + if (this._query.select_list !== undefined) { + for (i = 0; i < this._query.select_list; i += 1) { + property = this._query.select_list[i]; + if (select_list.indexOf(property) < 0) { + select_list.push(property); + } + } + } + if (this._id_mapped) { + // modify here for future way to map id + select_list.push(this._id_mapped); + } + if (option.query !== undefined) { + query = mapQuery(QueryFactory.create(option.query)); + } + + if (this._query.query !== undefined) { + if (query === undefined) { + query = this._query.query; + } + query = new ComplexQuery({ + operator: "AND", + query_list: [query, this._query.query], + type: "complex" + }); + } + + if (query !== undefined) { + query = Query.objectToSearchText(query); + } + return this._sub_storage.allDocs( + { + query: query, + select_list: select_list, + sort_on: sort_on, + limit: option.limit + } + ) + .push(function (result) { + var sub_doc, map_info = storage._map_id || ["equalSubId"]; + for (i = 0; i < result.data.total_rows; i += 1) { + sub_doc = result.data.rows[i].value; + result.data.rows[i].id = + mapping_function[map_info[0]].mapToId( + storage, + sub_doc, + result.data.rows[i].id, + map_info[1] + ); + result.data.rows[i].value = + mapToMainDocument( + storage, + sub_doc + ); + } + return result.data.rows; + }); + }; + + jIO.addStorage('mapping', MappingStorage); +}(jIO, RSVP, UriTemplate, SimpleQuery, ComplexQuery, QueryFactory, Query, + FormData)); \ No newline at end of file diff --git a/test/jio.storage/mappingstorage.tests.js b/test/jio.storage/mappingstorage.tests.js new file mode 100644 index 0000000000000000000000000000000000000000..4ad1436f40e61f934b6c8d571d75a99e1974d8fb --- /dev/null +++ b/test/jio.storage/mappingstorage.tests.js @@ -0,0 +1,1596 @@ +/*jslint indent:2, maxlen: 80, nomen: true */ +/*global jIO, QUnit, 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 Storage2713() { + return this; + } + jIO.addStorage('mappingstorage2713', Storage2713); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.constructor + ///////////////////////////////////////////////////////////////// + module("mappingStorage.constructor"); + test("create substorage", function () { + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "mappingstorage2713" + } + }); + + ok(jio.__storage._sub_storage instanceof jio.constructor); + equal(jio.__storage._sub_storage.__type, "mappingstorage2713"); + + deepEqual(jio.__storage._mapping_dict, {}); + deepEqual(jio.__storage._attachment_mapping_dict, {}); + deepEqual(jio.__storage._query, {}); + equal(jio.__storage._map_all_property, true); + + }); + + test("accept parameters", function () { + var jio = jIO.createJIO({ + type: "mapping", + map_all_property: false, + query: {"query": 'foo: "bar"'}, + attachment: {"foo": {"get": "bar"}}, + property: { "bar": ["equalSubProperty", "foo"]}, + id: ["equalSubProperty", "otherId"], + sub_storage: { + type: "mappingstorage2713" + } + }); + + deepEqual( + jio.__storage._mapping_dict, + {"bar": ["equalSubProperty", "foo"], "otherId": ["keep"]} + ); + deepEqual(jio.__storage._map_id, ["equalSubProperty", "otherId"]); + equal(jio.__storage._query.query.key, "foo"); + equal(jio.__storage._query.query.value, "bar"); + equal(jio.__storage._query.query.type, "simple"); + deepEqual(jio.__storage._attachment_mapping_dict, {"foo": {"get": "bar"}}); + equal(jio.__storage._map_all_property, false); + + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.get + ///////////////////////////////////////////////////////////////// + module("mappingStorage.get"); + test("called substorage get", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + property: {"title": ["equalSubProperty", "title"]}, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.get = function (id) { + equal(id, "bar", "get 2713 called"); + return {title: "foo"}; + }; + + jio.get("bar") + .push(function (result) { + deepEqual(result, { + "title": "foo" + }, "Check document"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with query and id equalSubProperty", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", 'otherId'], + query: {"query": 'otherTitle: "foo"'}, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + Storage2713.prototype.buildQuery = function (options) { + equal( + options.query, + '( otherId: "42" AND otherTitle: "foo" )', + "allDoc 2713 called" + ); + return [{id: "2713"}]; + }; + + Storage2713.prototype.get = function (id) { + equal(id, "2713", "get 2713 called"); + return {"title": "foo", "otherId": "42"}; + }; + + jio.get("42") + .push(function (result) { + deepEqual(result, { + "title": "foo", + "otherId": "42" + }); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with id equalSubProperty", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + Storage2713.prototype.buildQuery = function (options) { + equal(options.query, 'otherId: "42"', "allDoc 2713 called"); + return [{id: "2713"}]; + }; + + Storage2713.prototype.get = function (id) { + equal(id, "2713", "get 2713 called"); + return {"title": "foo", "otherId": "42"}; + }; + + jio.get("42") + .push(function (result) { + deepEqual(result, { + "title": "foo", + "otherId": "42" + }); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with prop equalSubProperty", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + property: { + "title": ["equalSubProperty", "otherTitle"] + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.get = function (id) { + equal(id, "bar", "get 2713 called"); + return {otherTitle: "foo"}; + }; + + jio.get("bar") + .push(function (result) { + deepEqual(result, { + "title": "foo" + }); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with prop equalSubId", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + property: {"title": ["equalSubId"]}, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.get = function (id) { + equal(id, "bar", "get 2713 called"); + return {}; + }; + + jio.get("bar") + .push(function (result) { + deepEqual(result, { + "title": "bar" + }); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + + test("with prop ignore", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + property: { + "title": ["ignore"] + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.get = function (id) { + equal(id, "bar", "get 2713 called"); + return {"title": "foo", "foo": "bar"}; + }; + + jio.get("bar") + .push(function (result) { + deepEqual(result, { + "foo": "bar" + }); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with switchPropertyValue", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + property: { + "title": ["switchPropertyValue", [ + "subTitle", + {"mytitle": "title", "yourtitle": "othertitle"} + ]], + "subTitle": ["ignore"] + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.get = function (id) { + equal(id, "bar", "get 2713 called"); + return {"subTitle": "title"}; + }; + + jio.get("bar") + .push(function (result) { + deepEqual(result, { + "title": "mytitle" + }); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.put + ///////////////////////////////////////////////////////////////// + module("mappingStorage.put"); + + test("substorage put called", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + property: { + "title": ["equalSubProperty", "title"] + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.put = function (id, param) { + equal(id, "bar", "put 2713 called"); + deepEqual(param, {"title": "foo"}, "put 2713 called"); + return id; + }; + + jio.put("bar", {"title": "foo"}) + .push(function (result) { + equal(result, "bar"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with id equalSubProperty", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.post = function (doc) { + deepEqual(doc, + {"otherId": "42", "title": "foo"}, "post 2713 called"); + return "bar"; + }; + + Storage2713.prototype.buildQuery = function (option) { + equal(option.query, 'otherId: "42"', "allDocs 2713 called"); + return []; + }; + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + jio.put("42", {"title": "foo"}) + .push(function (result) { + equal(result, "42"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with id equalSubProperty and prop equalSubId", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + property: { + "title": ["equalSubId"] + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.put = function (id, doc) { + deepEqual(doc, + {"otherId": "42", "title": "bar"}, "post 2713 called"); + equal(id, "bar"); + return "bar"; + }; + + jio.put("42", {"title": "bar"}) + .push(function (result) { + equal(result, "42"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with prop equalSubId", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + property: {"title": ["equalSubId"]}, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.put = function (id, param) { + equal(id, "2713", "put 2713 called"); + deepEqual(param, {"foo": "bar", "title": "2713"}, "put 2713 called"); + return id; + }; + + jio.put("bar", {"title": "2713", "foo": "bar"}) + .push(function (result) { + equal(result, "bar"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with prop equalSubProperty", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + property: {"title": ["equalSubProperty", "subTitle"]}, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.put = function (id, param) { + equal(id, "bar", "put 2713 called"); + deepEqual(param, {"subTitle": "foo"}, "put 2713 called"); + return id; + }; + + jio.put("bar", {"title": "foo"}) + .push(function (result) { + equal(result, "bar"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with prop equalValues", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + property: {"title": ["equalValue", "foobar"]}, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.put = function (id, param) { + equal(id, "bar", "put 2713 called"); + deepEqual(param, {"title": "foobar"}, "put 2713 called"); + return id; + }; + + jio.put("bar", {}) + .push(function (result) { + equal(result, "bar"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + test("with switchPropertyValue", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + property: { + "title": ["switchPropertyValue", [ + "subTitle", + {"mytitle": "title", "yourtitle": "othertitle"} + ]] + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.put = function (id, doc) { + equal(id, "bar", "put 2713 called"); + deepEqual(doc, {"subTitle": "title"}, "put 2713 called"); + return id; + }; + + jio.put("bar", {"title": "mytitle"}) + .push(function (result) { + equal(result, "bar"); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.remove + ///////////////////////////////////////////////////////////////// + module("mappingStorage.remove"); + + test("with substorage remove", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.remove = function (id) { + equal(id, "bar", "remove 2713 called"); + return id; + }; + + jio.remove("bar", {"title": "foo"}) + .push(function (result) { + equal(result, "bar"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with id mapped", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + Storage2713.prototype.buildQuery = function (options) { + equal(options.query, 'otherId: "42"', "allDoc 2713 called"); + return [{id: "2713"}]; + }; + + Storage2713.prototype.remove = function (id) { + equal(id, "2713", "get 2713 called"); + return "foo"; + }; + + jio.remove("42") + .push(function (result) { + equal(result, "42"); + }).push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.post + ///////////////////////////////////////////////////////////////// + module("mappingStorage.post"); + + test("with id equalSubProperty, no id in doc", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.post = function () { + return false; + }; + + jio.post({"title": "foo"}) + .push(undefined, function (error) { + equal(error.message, "post is not supported with id mapped"); + equal(error.status_code, 400); + }) + .always(function () { + start(); + }); + }); + + test("with id equalSubProperty and id in doc", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.buildQuery = function (options) { + equal(options.query, 'otherId: "bar"', "allDoc 2713 called"); + return []; + }; + + Storage2713.prototype.post = function (doc) { + deepEqual(doc, {"title": "foo", "otherId": "bar"}, "post 2713 called"); + return "bar"; + }; + + Storage2713.prototype.put = function (id, doc) { + equal(id, "bar", "put 2713 called"); + deepEqual(doc, { + "title": "foo", + "otherId": "bar" + }, "put 2713 called"); + return "bar"; + }; + + jio.post({"title": "foo", "otherId": "bar"}) + .push(function (result) { + equal(result, "bar"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with equalSubId and id in doc", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + property: {"otherId": ["equalSubId"]}, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.put = function (id, doc) { + deepEqual(doc, {"title": "foo", "otherId": "bar"}, "put 2713 called"); + equal(id, "bar", "put 2713 called"); + return "bar"; + }; + + jio.post({"title": "foo", "otherId": "bar"}) + .push(function (result) { + equal(result, "bar"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + ///////////////////////////////////////////////////////////////// + // mappingStorage.putAttachment + ///////////////////////////////////////////////////////////////// + module("mappingStorage.putAttachment"); + + test("sub_storage putAttachment called", function () { + stop(); + expect(4); + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "mappingstorage2713" + } + }), blob = new Blob([""]); + + Storage2713.prototype.putAttachment = function (doc_id, + attachment_id, attachment) { + equal(doc_id, "42", "putAttachment 2713 called"); + equal(attachment_id, "2713", "putAttachment 2713 called"); + deepEqual(attachment, blob, "putAttachment 2713 called"); + return doc_id; + }; + + jio.putAttachment("42", "2713", blob) + .push(function (result) { + equal(result, "2713"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with UriTemplate", function () { + stop(); + expect(4); + + var jio = jIO.createJIO({ + type: "mapping", + attachment: { + "2713": {"put": {"uri_template": "www.2713.foo/{id}"}} + }, + sub_storage: { + type: "mappingstorage2713" + } + }), blob = new Blob([""]); + + Storage2713.prototype.putAttachment = function (doc_id, + attachment_id, attachment) { + equal(doc_id, "42", "putAttachment 2713 called"); + equal(attachment_id, "www.2713.foo/42", "putAttachment 2713 called"); + deepEqual(attachment, blob, "putAttachment 2713 called"); + return doc_id; + }; + + jio.putAttachment("42", "2713", blob) + .push(function (result) { + equal(result, "2713"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with UriTemplate and id equalSubProperty", function () { + stop(); + expect(5); + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + attachment: { + "2713": {"put": {"uri_template": "www.2713.foo/{id}"}} + }, + sub_storage: { + type: "mappingstorage2713" + } + }), blob = new Blob([""]); + + Storage2713.prototype.putAttachment = function (id, + attachment_id, attachment) { + equal(id, "13", "putAttachment 2713 called"); + equal(attachment_id, "www.2713.foo/13", "putAttachment 2713 called"); + deepEqual(attachment, blob, "putAttachment 2713 called"); + return id; + }; + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + Storage2713.prototype.buildQuery = function (option) { + equal(option.query, 'otherId: "42"'); + return [{"id": "13"}]; + }; + + jio.putAttachment("42", "2713", blob) + .push(function (result) { + equal(result, "2713"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.getAttachment + ///////////////////////////////////////////////////////////////// + module("mappingStorage.getAttachment"); + test("sub_storage getAttachment called", function () { + stop(); + expect(3); + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "mappingstorage2713" + } + }), blob = new Blob([""]); + + Storage2713.prototype.getAttachment = function (doc_id, attachment) { + equal(doc_id, "42", "getAttachment 2713 called"); + equal(attachment, "2713", "getAttachment 2713 called"); + return blob; + }; + + jio.getAttachment("42", "2713") + .push(function (result) { + deepEqual(result, blob); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with UriTemplate", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + attachment: { + "2713": {"get": {"uri_template": "www.2713/{id}/ok.com"}} + }, + sub_storage: { + type: "mappingstorage2713" + } + }), blob = new Blob([""]); + + Storage2713.prototype.getAttachment = function (doc_id, attachment) { + equal(attachment, "www.2713/42/ok.com", "getAttachment 2713 called"); + equal(doc_id, "42", "getAttachment 2713 called"); + return blob; + }; + + jio.getAttachment("42", "2713") + .push(function (result) { + deepEqual(result, blob); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with UriTemplate and id mapped", function () { + stop(); + expect(4); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + attachment: { + "2713": {"get": {"uri_template": "www.2713.foo/{id}"}} + }, + sub_storage: { + type: "mappingstorage2713" + } + }), blob = new Blob([""]); + + Storage2713.prototype.getAttachment = function (id, + attachment_id) { + equal(id, "13", "getAttachment 2713 called"); + equal(attachment_id, "www.2713.foo/13", "getAttachment 2713 called"); + return blob; + }; + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + Storage2713.prototype.buildQuery = function (option) { + equal(option.query, 'otherId: "42"'); + return [{"id": "13"}]; + }; + + jio.getAttachment("42", "2713") + .push(function (result) { + deepEqual(result, blob); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.removeAttachment + ///////////////////////////////////////////////////////////////// + module("mappingStorage.removeAttachment"); + test("sub_storage removeAttachment called", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.removeAttachment = function (doc_id, attachment) { + equal(doc_id, "42", "removeAttachment 2713 called"); + equal(attachment, "2713", "getAttachment 2713 called"); + return doc_id; + }; + + jio.removeAttachment("42", "2713") + .push(function (result) { + deepEqual(result, "2713"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with use UriTemplate", function () { + stop(); + expect(3); + + var jio = jIO.createJIO({ + type: "mapping", + attachment: { + "2713": {"remove": {"uri_template": "www.2713/{id}.bar"}} + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.removeAttachment = function (doc_id, attachment) { + equal(doc_id, "42", "removeAttachment 2713 called"); + equal(attachment, "www.2713/42.bar", "removeAttachment 2713 called"); + return doc_id; + }; + + jio.removeAttachment("42", "2713") + .push(function (result) { + deepEqual(result, "2713"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with UriTemplate and id equalSubProperty", function () { + stop(); + expect(4); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + attachment: { + "2713": {"remove": {"uri_template": "www.2713.foo/{id}"}} + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.removeAttachment = function (id, + attachment_id) { + equal(id, "13", "removeAttachment 2713 called"); + equal(attachment_id, "www.2713.foo/13", "removeAttachment 2713 called"); + return id; + }; + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + Storage2713.prototype.buildQuery = function (option) { + equal(option.query, 'otherId: "42"'); + return [{"id": "13"}]; + }; + + jio.removeAttachment("42", "2713") + .push(function (result) { + equal(result, "2713"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.allAttachments + ///////////////////////////////////////////////////////////////// + module("mappingStorage.allAttachments"); + test("sub_storage allAttachments called", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.allAttachments = function (doc_id) { + equal(doc_id, "42", "allAttachments 2713 called"); + return {}; + }; + + jio.allAttachments("42") + .push(function (result) { + deepEqual(result, {}); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with UriTemplate", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + attachment: { + "2713": {"get": {"uri_template": "www.2713.bar"}} + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.allAttachments = function (doc_id) { + equal(doc_id, "42", "allAttachments 2713 called"); + return {"www.2713.bar": {}}; + }; + + jio.allAttachments("42") + .push(function (result) { + deepEqual(result, {"2713": {}}); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.allDocs + ///////////////////////////////////////////////////////////////// + module("mappingStorage.buildQuery"); + test("with complex query", function () { + stop(); + expect(1); + + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "query", + sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + } + }); + + jio.put("42", {"title": "foo", "smth": "bar"}) + .push(function () { + return jio.allDocs({ + query: '(title: "foo") AND (smth: "bar")', + select_list: ["title", "smth"], + sort_on: [["title", "descending"]] + }); + }) + .push(function (result) { + deepEqual(result, + { + "data": { + "rows": [ + { + "id": "42", + "value": { + "title": "foo", + "smth": "bar" + }, + "doc": {} + } + ], + "total_rows": 1 + } + }, "allDocs check"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with complex query, id and prop equalSubProperty", function () { + stop(); + expect(1); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + property: { + "title": ["equalSubProperty", "otherTitle"], + "smth": ["equalSubProperty", "otherSmth"] + }, + sub_storage: { + type: "query", + sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + } + }); + + jio.put("42", + { + "title": "foo", + "smth": "bar" + }) + .push(function () { + return jio.put( + "2713", + { + "title": "bar", + "smth": "foo" + } + ); + }) + .push(function () { + return jio.allDocs({ + query: '(title: "foo") OR (title: "bar")', + select_list: ["title", "smth"], + sort_on: [["title", "descending"]] + }); + }) + .push(function (result) { + deepEqual(result, + { + "data": { + "rows": [ + { + "id": "42", + "value": { + "title": "foo", + "smth": "bar", + "otherId": "42" + }, + "doc": {} + }, + { + "id": "2713", + "value": { + "title": "bar", + "smth": "foo", + "otherId": "2713" + }, + "doc": {} + } + ], + "total_rows": 2 + } + }, "allDocs check"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("without option, id and prop equalSubProperty", function () { + stop(); + expect(1); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + property: { + "title": ["equalSubProperty", "otherTitle"] + }, + sub_storage: { + type: "query", + sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + } + }); + + jio.put("42", + { + "title": "foo", + "smth": "bar" + }) + .push(function () { + return jio.allDocs(); + }) + .push(function (result) { + deepEqual(result, + { + "data": { + "rows": [ + { + "id": "42", + "value": { + "otherId": "42" + }, + "doc": {} + } + ], + "total_rows": 1 + } + }, "allDocs check"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with id and prop equalSubProperty", function () { + stop(); + expect(1); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + property: { + "title": ["equalSubProperty", "otherTitle"] + }, + sub_storage: { + type: "query", + sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + } + }); + + jio.put("42", + { + "title": "foo", + "smth": "bar" + }) + .push(function () { + return jio.allDocs({ + query: 'title: "foo"', + select_list: ["title", "smth"] + }); + }) + .push(function (result) { + deepEqual(result, + { + "data": { + "rows": [ + { + "id": "42", + "value": {"title": "foo", "smth": "bar", "otherId": "42"}, + "doc": {} + } + ], + "total_rows": 1 + } + }, "allDocs check"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with id and prop equalSubProperty and query", function () { + stop(); + expect(1); + + var jio = jIO.createJIO({ + type: "mapping", + query: {"query": 'otherId: "42"'}, + id: ["equalSubProperty", "otherId"], + property: { + "title": ["equalSubProperty", "otherTitle"] + }, + sub_storage: { + type: "query", + sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + } + }); + + jio.put("42", + { + "title": "foo", + "smth": "bar" + }) + .push(function () { + return jio.allDocs({ + query: 'title: "foo"', + select_list: ["title"] + }); + }) + .push(function (result) { + deepEqual(result, + { + "data": { + "rows": [ + { + "id": "42", + "value": { + "otherId": "42", + "title": "foo" + }, + "doc": {} + } + ], + "total_rows": 1 + } + }, "allDocs check"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + test("with extended_search", function () { + stop(); + expect(1); + + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "query", + sub_storage: { + type: "uuid", + sub_storage: { + type: "memory" + } + } + } + }); + + jio.put("42", + { + "title": "foo", + "smth": "bar" + }) + .push(function () { + return jio.allDocs({ + query: "foo", + select_list: ["title"] + }); + }) + .push(function (result) { + deepEqual(result, + { + "data": { + "rows": [ + { + "id": "42", + "value": { + "title": "foo" + }, + "doc": {} + } + ], + "total_rows": 1 + } + }, "allDocs check"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.bulk + ///////////////////////////////////////////////////////////////// + module("mappingstorage.bulk"); + test("with id and prop equalSubProperty", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + id: ["equalSubProperty", "otherId"], + property: { + "title": ["equalSubProperty", "otherTitle"] + }, + sub_storage: { + type: "mappingstorage2713" + } + }); + + Storage2713.prototype.hasCapacity = function () { + return true; + }; + + Storage2713.prototype.buildQuery = function (option) { + if (option.query === 'otherId: "id1"') { + return [{id: "foo"}]; + } + if (option.query === 'otherId: "id2"') { + return [{id: "bar"}]; + } + throw new Error("invalid option:" + option.toString()); + }; + + Storage2713.prototype.bulk = function (args) { + deepEqual( + args, + [{ + method: "get", + parameter_list: ["foo"] + }, { + method: "get", + parameter_list: ["bar"] + }], + "bulk 2713 called" + ); + return [ + { + "otherId": "foo", + "otherTitle": "bar", + "bar": "foo" + }, { + "otherId": "bar", + "otherTitle": "foo", + "foo": "bar" + } + ]; + }; + + jio.bulk([{ + method: "get", + parameter_list: ["id1"] + }, { + method: "get", + parameter_list: ["id2"] + }]) + .push(function (result) { + deepEqual( + result, + [{ + "title": "bar", + "otherId": "foo", + "bar": "foo" + }, { + "title": "foo", + "otherId": "bar", + "foo": "bar" + }], + "bulk test" + ); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + + ///////////////////////////////////////////////////////////////// + // mappingStorage.repair + ///////////////////////////////////////////////////////////////// + module("mappingStorage.repair"); + + test("substorage repair called", function () { + stop(); + expect(2); + + var jio = jIO.createJIO({ + type: "mapping", + sub_storage: { + type: "mappingstorage2713" + }, + property: { + "title": ["equalSubProperty", "title"] + } + }); + + Storage2713.prototype.repair = function (id_list) { + deepEqual(id_list, ["foo", "bar"], "repair 2713 called"); + return "foobar"; + }; + + jio.repair(["foo", "bar"]) + .push(function (result) { + equal(result, "foobar", "Check repair"); + }) + .push(undefined, function (error) { + ok(false, error); + }) + .always(function () { + start(); + }); + }); + +}(jIO, QUnit, Blob)); \ No newline at end of file