Commit b9464f1a authored by Aurélien Vermylen's avatar Aurélien Vermylen

Merge branch 'master' into clearroad

Conflicts:
	dist/jio-latest.js
	dist/jio-latest.min.js
parents c01fe22d 522f08a4
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
{ {
"name": "jio", "name": "jio",
"version": "v3.23.1", "version": "v3.25.0",
"license": "LGPLv3", "license": "LGPLv3",
"author": "Nexedi SA", "author": "Nexedi SA",
"contributors": [ "contributors": [
......
...@@ -7,27 +7,18 @@ ...@@ -7,27 +7,18 @@
* JIO Dropbox Storage. Type = "dropbox". * JIO Dropbox Storage. Type = "dropbox".
* Dropbox "database" storage. * Dropbox "database" storage.
*/ */
/*global Blob, jIO, RSVP, UriTemplate*/ /*global Blob, jIO, RSVP*/
/*jslint nomen: true*/ /*jslint nomen: true*/
(function (jIO, RSVP, Blob, UriTemplate) { (function (jIO, RSVP, Blob, JSON) {
"use strict"; "use strict";
var UPLOAD_URL = "https://content.dropboxapi.com/1/files_put/" + var GET_URL = "https://content.dropboxapi.com/2/files/download",
"{+root}{+id}{+name}{?access_token}", UPLOAD_URL = "https://content.dropboxapi.com/2/files/upload",
upload_template = UriTemplate.parse(UPLOAD_URL), REMOVE_URL = "https://api.dropboxapi.com/2/files/delete_v2",
CREATE_DIR_URL = "https://api.dropboxapi.com/1/fileops/create_folder" + CREATE_DIR_URL = "https://api.dropboxapi.com/2/files/create_folder_v2",
"{?access_token,root,path}", METADATA_URL = "https://api.dropboxapi.com/2/files/get_metadata",
create_dir_template = UriTemplate.parse(CREATE_DIR_URL), LIST_FOLDER_URL = "https://api.dropboxapi.com/2/files/list_folder",
REMOVE_URL = "https://api.dropboxapi.com/1/fileops/delete/" + LIST_MORE_URL = "https://api.dropboxapi.com/2/files/list_folder/continue";
"{?access_token,root,path}",
remote_template = UriTemplate.parse(REMOVE_URL),
GET_URL = "https://content.dropboxapi.com/1/files" +
"{/root,id}{+name}{?access_token}",
get_template = UriTemplate.parse(GET_URL),
//LIST_URL = 'https://api.dropboxapi.com/1/metadata/sandbox/';
METADATA_URL = "https://api.dropboxapi.com/1/metadata" +
"{/root}{+id}{?access_token}",
metadata_template = UriTemplate.parse(METADATA_URL);
function restrictDocumentId(id) { function restrictDocumentId(id) {
if (id.indexOf("/") !== 0) { if (id.indexOf("/") !== 0) {
...@@ -38,7 +29,7 @@ ...@@ -38,7 +29,7 @@
throw new jIO.util.jIOError("id " + id + " is forbidden (no end /)", throw new jIO.util.jIOError("id " + id + " is forbidden (no end /)",
400); 400);
} }
return id; return id.slice(0, -1);
} }
function restrictAttachmentId(id) { function restrictAttachmentId(id) {
...@@ -48,6 +39,66 @@ ...@@ -48,6 +39,66 @@
} }
} }
function recursiveAllAttachments(result, token, id, cursor) {
var data,
url;
if (cursor === undefined) {
data = {
"path": id,
"recursive": false,
"include_media_info": false,
"include_deleted": false,
"include_has_explicit_shared_members": false,
"include_mounted_folders": true
};
url = LIST_FOLDER_URL;
} else {
data = {"cursor": cursor};
url = LIST_MORE_URL;
}
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
type: "POST",
url: url,
headers: {
"Authorization": "Bearer " + token,
"Content-Type": "application/json"
},
data: JSON.stringify(data)
});
})
.push(function (evt) {
var obj = JSON.parse(evt.target.response || evt.target.responseText),
i;
for (i = 0; i < obj.entries.length; i += 1) {
if (obj.entries[i][".tag"] === "file") {
result[obj.entries[i].name] = {};
}
}
if (obj.has_more) {
return recursiveAllAttachments(result, token, id, obj.cursor);
}
return result;
}, function (error) {
if (error.target !== undefined && error.target.status === 409) {
var err_content = JSON.parse(error.target.response ||
error.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_folder')) {
throw new jIO.util.jIOError("Not a directory: " + id + "/",
404);
}
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find document: " + id + "/",
404);
}
}
throw error;
});
}
/** /**
* The JIO Dropbox Storage extension * The JIO Dropbox Storage extension
* *
...@@ -59,12 +110,7 @@ ...@@ -59,12 +110,7 @@
throw new TypeError("Access Token' must be a string " + throw new TypeError("Access Token' must be a string " +
"which contains more than one character."); "which contains more than one character.");
} }
if (typeof spec.root !== 'string' || !spec.root ||
(spec.root !== "dropbox" && spec.root !== "sandbox")) {
throw new TypeError("root must be 'dropbox' or 'sandbox'");
}
this._access_token = spec.access_token; this._access_token = spec.access_token;
this._root = spec.root;
} }
DropboxStorage.prototype.put = function (id, param) { DropboxStorage.prototype.put = function (id, param) {
...@@ -79,19 +125,25 @@ ...@@ -79,19 +125,25 @@
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "POST", type: "POST",
url: create_dir_template.expand({ url: CREATE_DIR_URL,
access_token: that._access_token, headers: {
root: that._root, "Authorization": "Bearer " + that._access_token,
path: id "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id, "autorename": false})
}); });
}) })
.push(undefined, function (err) { .push(undefined, function (err) {
if ((err.target !== undefined) && if ((err.target !== undefined) &&
(err.target.status === 405)) { (err.target.status === 409)) {
var err_content = JSON.parse(err.target.response ||
err.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'conflict')) {
// Directory already exists, no need to fail // Directory already exists, no need to fail
return; return;
} }
}
throw err; throw err;
}); });
}; };
...@@ -100,11 +152,12 @@ ...@@ -100,11 +152,12 @@
id = restrictDocumentId(id); id = restrictDocumentId(id);
return jIO.util.ajax({ return jIO.util.ajax({
type: "POST", type: "POST",
url: remote_template.expand({ url: REMOVE_URL,
access_token: this._access_token, headers: {
root: this._root, "Authorization": "Bearer " + this._access_token,
path: id "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id})
}); });
}; };
...@@ -119,64 +172,39 @@ ...@@ -119,64 +172,39 @@
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "GET", type: "POST",
url: metadata_template.expand({ url: METADATA_URL,
access_token: that._access_token, headers: {
root: that._root, "Authorization": "Bearer " + that._access_token,
id: id "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id})
}); });
}) })
.push(function (evt) { .push(function (evt) {
var obj = JSON.parse(evt.target.response || var obj = JSON.parse(evt.target.response ||
evt.target.responseText); evt.target.responseText);
if (obj.is_dir) { if (obj[".tag"] === "folder") {
return {}; return {};
} }
throw new jIO.util.jIOError("Not a directory: " + id, 404); throw new jIO.util.jIOError("Not a directory: " + id + "/", 404);
}, function (error) { }, function (error) {
if (error.target !== undefined && error.target.status === 404) { if (error.target !== undefined && error.target.status === 409) {
throw new jIO.util.jIOError("Cannot find document: " + id, 404); var err_content = JSON.parse(error.target.response ||
error.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find document: " + id + "/",
404);
}
} }
throw error; throw error;
}); });
}; };
DropboxStorage.prototype.allAttachments = function (id) { DropboxStorage.prototype.allAttachments = function (id) {
var that = this;
id = restrictDocumentId(id); id = restrictDocumentId(id);
return recursiveAllAttachments({}, this._access_token, id);
return new RSVP.Queue()
.push(function () {
return jIO.util.ajax({
type: "GET",
url: metadata_template.expand({
access_token: that._access_token,
root: that._root,
id: id
})
});
})
.push(function (evt) {
var obj = JSON.parse(evt.target.response || evt.target.responseText),
i,
result = {};
if (!obj.is_dir) {
throw new jIO.util.jIOError("Not a directory: " + id, 404);
}
for (i = 0; i < obj.contents.length; i += 1) {
if (!obj.contents[i].is_dir) {
result[obj.contents[i].path.split("/").pop()] = {};
}
}
return result;
}, function (error) {
if (error.target !== undefined && error.target.status === 404) {
throw new jIO.util.jIOError("Cannot find document: " + id, 404);
}
throw error;
});
}; };
//currently, putAttachment will fail with files larger than 150MB, //currently, putAttachment will fail with files larger than 150MB,
...@@ -191,20 +219,24 @@ ...@@ -191,20 +219,24 @@
restrictAttachmentId(name); restrictAttachmentId(name);
return jIO.util.ajax({ return jIO.util.ajax({
type: "PUT", type: "POST",
url: upload_template.expand({ url: UPLOAD_URL,
root: this._root, headers: {
id: id, "Authorization": "Bearer " + this._access_token,
name: name, "Content-Type": "application/octet-stream",
access_token: this._access_token "Dropbox-API-Arg": JSON.stringify({
}), "path": id + "/" + name,
dataType: blob.type, "mode": "overwrite",
"autorename": false,
"mute": false
})
},
data: blob data: blob
}); });
}; };
DropboxStorage.prototype.getAttachment = function (id, name) { DropboxStorage.prototype.getAttachment = function (id, name) {
var that = this; var context = this;
id = restrictDocumentId(id); id = restrictDocumentId(id);
restrictAttachmentId(name); restrictAttachmentId(name);
...@@ -212,26 +244,48 @@ ...@@ -212,26 +244,48 @@
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "GET", url: GET_URL,
type: "POST",
dataType: "blob", dataType: "blob",
url: get_template.expand({ headers: {
root: that._root, "Authorization": "Bearer " + context._access_token,
id: id, "Dropbox-API-Arg": JSON.stringify({"path": id + "/" + name})
name: name, }
access_token: that._access_token
})
}); });
}) })
.push(function (evt) { .push(function (evt) {
if (evt.target.response instanceof Blob) {
return evt.target.response;
}
return new Blob( return new Blob(
[evt.target.response || evt.target.responseText], [evt.target.responseText],
{"type": evt.target.getResponseHeader('Content-Type') || {"type": evt.target.getResponseHeader('Content-Type') ||
"application/octet-stream"} "application/octet-stream"}
); );
}, function (error) { }, function (error) {
if (error.target !== undefined && error.target.status === 404) { if (error.target !== undefined && error.target.status === 409) {
if (!(error.target.response instanceof Blob)) {
var err_content = JSON.parse(error.target.responseText);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find attachment: " + throw new jIO.util.jIOError("Cannot find attachment: " +
id + ", " + name, 404); id + "/, " + name, 404);
}
throw error;
}
return new RSVP.Queue()
.push(function () {
return jIO.util.readBlobAsText(error.target.response);
})
.push(function (evt) {
var err_content = JSON.parse(evt.target.result);
if ((err_content.error['.tag'] === 'path') &&
(err_content.error.path['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find attachment: " +
id + "/, " + name, 404);
}
throw error;
});
} }
throw error; throw error;
}); });
...@@ -248,16 +302,22 @@ ...@@ -248,16 +302,22 @@
.push(function () { .push(function () {
return jIO.util.ajax({ return jIO.util.ajax({
type: "POST", type: "POST",
url: remote_template.expand({ url: REMOVE_URL,
access_token: that._access_token, headers: {
root: that._root, "Authorization": "Bearer " + that._access_token,
path: id + name "Content-Type": "application/json"
}) },
data: JSON.stringify({"path": id + "/" + name})
}); });
}).push(undefined, function (error) { }).push(undefined, function (error) {
if (error.target !== undefined && error.target.status === 404) { if (error.target !== undefined && error.target.status === 409) {
var err_content = JSON.parse(error.target.response ||
error.target.responseText);
if ((err_content.error['.tag'] === 'path_lookup') &&
(err_content.error.path_lookup['.tag'] === 'not_found')) {
throw new jIO.util.jIOError("Cannot find attachment: " + throw new jIO.util.jIOError("Cannot find attachment: " +
id + ", " + name, 404); id + "/, " + name, 404);
}
} }
throw error; throw error;
}); });
...@@ -265,4 +325,4 @@ ...@@ -265,4 +325,4 @@
jIO.addStorage('dropbox', DropboxStorage); jIO.addStorage('dropbox', DropboxStorage);
}(jIO, RSVP, Blob, UriTemplate)); }(jIO, RSVP, Blob, JSON));
/*jslint nomen: true*/ /*jslint nomen: true*/
/*global RSVP*/ /*global RSVP, jiodate*/
(function (jIO, RSVP) { (function (jIO, RSVP, jiodate) {
"use strict"; "use strict";
function dateType(str) {
return jiodate.JIODate(new Date(str).toISOString());
}
function initKeySchema(storage, spec) {
var property;
for (property in spec.schema) {
if (spec.schema.hasOwnProperty(property)) {
if (spec.schema[property].type === "string" &&
spec.schema[property].format === "date-time") {
storage._key_schema.key_set[property] = {
read_from: property,
cast_to: "dateType"
};
if (storage._key_schema.cast_lookup.dateType === undefined) {
storage._key_schema.cast_lookup.dateType = dateType;
}
} else {
throw new jIO.util.jIOError(
"Wrong schema for property: " + property,
400
);
}
}
}
}
/** /**
* The jIO QueryStorage extension * The jIO QueryStorage extension
* *
...@@ -11,7 +38,8 @@ ...@@ -11,7 +38,8 @@
*/ */
function QueryStorage(spec) { function QueryStorage(spec) {
this._sub_storage = jIO.createJIO(spec.sub_storage); this._sub_storage = jIO.createJIO(spec.sub_storage);
this._key_schema = spec.key_schema; this._key_schema = {key_set: {}, cast_lookup: {}};
initKeySchema(this, spec);
} }
QueryStorage.prototype.get = function () { QueryStorage.prototype.get = function () {
...@@ -211,4 +239,4 @@ ...@@ -211,4 +239,4 @@
jIO.addStorage('query', QueryStorage); jIO.addStorage('query', QueryStorage);
}(jIO, RSVP)); }(jIO, RSVP, jiodate));
...@@ -44,8 +44,8 @@ ...@@ -44,8 +44,8 @@
* @param {String} [way="ascending"] 'ascending' or 'descending' * @param {String} [way="ascending"] 'ascending' or 'descending'
* @return {Function} The sort function * @return {Function} The sort function
*/ */
function sortFunction(key, way) { function sortFunction(key, way, key_schema) {
var result; var result, cast_to;
if (way === 'descending') { if (way === 'descending') {
result = 1; result = 1;
} else if (way === 'ascending') { } else if (way === 'ascending') {
...@@ -54,6 +54,29 @@ ...@@ -54,6 +54,29 @@
throw new TypeError("Query.sortFunction(): " + throw new TypeError("Query.sortFunction(): " +
"Argument 2 must be 'ascending' or 'descending'"); "Argument 2 must be 'ascending' or 'descending'");
} }
if (key_schema !== undefined &&
key_schema.key_set !== undefined &&
key_schema.key_set[key] !== undefined &&
key_schema.key_set[key].cast_to !== undefined) {
if (typeof key_schema.key_set[key].cast_to === "string") {
cast_to = key_schema.cast_lookup[key_schema.key_set[key].cast_to];
} else {
cast_to = key_schema.key_set[key].cast_to;
}
return function (a, b) {
var f_a = cast_to(a[key]), f_b = cast_to(b[key]);
if (typeof f_b.cmp === 'function') {
return result * f_b.cmp(f_a);
}
if (f_a > f_b) {
return -result;
}
if (f_a < f_b) {
return result;
}
return 0;
};
}
return function (a, b) { return function (a, b) {
// this comparison is 5 times faster than json comparison // this comparison is 5 times faster than json comparison
var i, l; var i, l;
...@@ -78,6 +101,7 @@ ...@@ -78,6 +101,7 @@
}; };
} }
/** /**
* Sort a list of items, according to keys and directions. * Sort a list of items, according to keys and directions.
* *
...@@ -85,7 +109,7 @@ ...@@ -85,7 +109,7 @@
* @param {Array} list The item list to sort * @param {Array} list The item list to sort
* @return {Array} The filtered list * @return {Array} The filtered list
*/ */
function sortOn(sort_on_option, list) { function sortOn(sort_on_option, list, key_schema) {
var sort_index; var sort_index;
if (!Array.isArray(sort_on_option)) { if (!Array.isArray(sort_on_option)) {
throw new TypeError("jioquery.sortOn(): " + throw new TypeError("jioquery.sortOn(): " +
...@@ -95,7 +119,8 @@ ...@@ -95,7 +119,8 @@
sort_index -= 1) { sort_index -= 1) {
list.sort(sortFunction( list.sort(sortFunction(
sort_on_option[sort_index][0], sort_on_option[sort_index][0],
sort_on_option[sort_index][1] sort_on_option[sort_index][1],
key_schema
)); ));
} }
return list; return list;
...@@ -158,6 +183,35 @@ ...@@ -158,6 +183,35 @@
return list; return list;
} }
function checkKeySchema(key_schema) {
var prop;
if (key_schema !== undefined) {
if (typeof key_schema !== 'object') {
throw new TypeError("Query().create(): " +
"key_schema is not of type 'object'");
}
// key_set is mandatory
if (key_schema.key_set === undefined) {
throw new TypeError("Query().create(): " +
"key_schema has no 'key_set' property");
}
for (prop in key_schema) {
if (key_schema.hasOwnProperty(prop)) {
switch (prop) {
case 'key_set':
case 'cast_lookup':
case 'match_lookup':
break;
default:
throw new TypeError("Query().create(): " +
"key_schema has unknown property '" + prop + "'");
}
}
}
}
}
/** /**
* The query to use to filter a list of objects. * The query to use to filter a list of objects.
* This is an abstract class. * This is an abstract class.
...@@ -165,7 +219,10 @@ ...@@ -165,7 +219,10 @@
* @class Query * @class Query
* @constructor * @constructor
*/ */
function Query() { function Query(key_schema) {
checkKeySchema(key_schema);
this._key_schema = key_schema || {};
/** /**
* Called before parsing the query. Must be overridden! * Called before parsing the query. Must be overridden!
...@@ -238,7 +295,7 @@ ...@@ -238,7 +295,7 @@
} }
if (option.sort_on) { if (option.sort_on) {
sortOn(option.sort_on, item_list); sortOn(option.sort_on, item_list, this._key_schema);
} }
if (option.limit) { if (option.limit) {
...@@ -577,7 +634,7 @@ ...@@ -577,7 +634,7 @@
*/ */
QueryFactory.create = function (object, key_schema) { QueryFactory.create = function (object, key_schema) {
if (object === "") { if (object === "") {
return new Query(); return new Query(key_schema);
} }
if (typeof object === "string") { if (typeof object === "string") {
object = parseStringToObject(object); object = parseStringToObject(object);
...@@ -609,35 +666,6 @@ ...@@ -609,35 +666,6 @@
throw new TypeError("This object is not a query"); throw new TypeError("This object is not a query");
} }
function checkKeySchema(key_schema) {
var prop;
if (key_schema !== undefined) {
if (typeof key_schema !== 'object') {
throw new TypeError("SimpleQuery().create(): " +
"key_schema is not of type 'object'");
}
// key_set is mandatory
if (key_schema.key_set === undefined) {
throw new TypeError("SimpleQuery().create(): " +
"key_schema has no 'key_set' property");
}
for (prop in key_schema) {
if (key_schema.hasOwnProperty(prop)) {
switch (prop) {
case 'key_set':
case 'cast_lookup':
case 'match_lookup':
break;
default:
throw new TypeError("SimpleQuery().create(): " +
"key_schema has unknown property '" + prop + "'");
}
}
}
}
}
/** /**
* The SimpleQuery inherits from Query, and compares one metadata value * The SimpleQuery inherits from Query, and compares one metadata value
* *
...@@ -649,11 +677,7 @@ ...@@ -649,11 +677,7 @@
* @param {String} spec.value The value of the metadata to compare * @param {String} spec.value The value of the metadata to compare
*/ */
function SimpleQuery(spec, key_schema) { function SimpleQuery(spec, key_schema) {
Query.call(this); Query.call(this, key_schema);
checkKeySchema(key_schema);
this._key_schema = key_schema || {};
/** /**
* Operator to use to compare object values * Operator to use to compare object values
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
deepEqual = QUnit.deepEqual, deepEqual = QUnit.deepEqual,
equal = QUnit.equal, equal = QUnit.equal,
module = QUnit.module, module = QUnit.module,
throws = QUnit.throws,
token = "sample_token"; token = "sample_token";
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -21,31 +20,10 @@ ...@@ -21,31 +20,10 @@
test("create storage", function () { test("create storage", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "sandbox"
}); });
equal(jio.__type, "dropbox"); equal(jio.__type, "dropbox");
deepEqual(jio.__storage._access_token, token); deepEqual(jio.__storage._access_token, token);
deepEqual(jio.__storage._root, "sandbox");
});
test("reject invalid root", function () {
throws(
function () {
jIO.createJIO({
type: "dropbox",
access_token: token,
root : "foobar"
});
},
function (error) {
ok(error instanceof TypeError);
equal(error.message,
"root must be 'dropbox' or 'sandbox'");
return true;
}
);
}); });
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -60,8 +38,7 @@ ...@@ -60,8 +38,7 @@
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "dropbox"
}); });
}, },
teardown: function () { teardown: function () {
...@@ -71,8 +48,7 @@ ...@@ -71,8 +48,7 @@
}); });
test("put document", function () { test("put document", function () {
var url = "https://api.dropboxapi.com/1/fileops/create_folder?access_token=" var url = "https://api.dropboxapi.com/2/files/create_folder_v2",
+ token + "&root=dropbox&path=%2Fput1%2F",
server = this.server; server = this.server;
this.server.respondWith("POST", url, [201, { this.server.respondWith("POST", url, [201, {
"Content-Type": "text/xml" "Content-Type": "text/xml"
...@@ -87,10 +63,14 @@ ...@@ -87,10 +63,14 @@
equal(server.requests[0].method, "POST"); equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url); equal(server.requests[0].url, url);
equal(server.requests[0].status, 201); equal(server.requests[0].status, 201);
equal(server.requests[0].requestBody, undefined); deepEqual(JSON.parse(server.requests[0].requestBody), {
"path": "/put1",
"autorename": false
});
equal(server.requests[0].responseText, ""); equal(server.requests[0].responseText, "");
deepEqual(server.requests[0].requestHeaders, { deepEqual(server.requests[0].requestHeaders, {
"Content-Type": "text/plain;charset=utf-8" "Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
}); });
}) })
.fail(function (error) { .fail(function (error) {
...@@ -101,18 +81,53 @@ ...@@ -101,18 +81,53 @@
}); });
}); });
test("don't throw error when putting existing directory", function () { test("put sub document", function () {
var url = "https://api.dropboxapi.com/1/fileops/create_folder?access_token=" var url = "https://api.dropboxapi.com/2/files/create_folder_v2",
+ token + "&root=dropbox&path=%2Fexisting%2F",
server = this.server; server = this.server;
this.server.respondWith("POST", url, [405, { this.server.respondWith("POST", url, [201, {
"Content-Type": "text/xml" "Content-Type": "text/xml"
}, "POST" + url + "(Forbidden)"]); }, ""]);
stop();
expect(7);
this.jio.put("/put1/put2/", {})
.then(function () {
equal(server.requests.length, 1);
equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url);
equal(server.requests[0].status, 201);
deepEqual(JSON.parse(server.requests[0].requestBody), {
"path": "/put1/put2",
"autorename": false
});
equal(server.requests[0].responseText, "");
deepEqual(server.requests[0].requestHeaders, {
"Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("don't throw error when putting existing directory", function () {
var url = "https://api.dropboxapi.com/2/files/create_folder_v2",
server = this.server;
this.server.respondWith("POST", url, [409, {
"Content-Type": "application/json"
}, JSON.stringify(
{error: {'.tag': 'path', 'path': {'.tag': 'conflict'}}}
)]);
stop(); stop();
expect(1); expect(1);
this.jio.put("/existing/", {}) this.jio.put("/existing/", {})
.then(function () { .then(function () {
equal(server.requests[0].status, 405); equal(server.requests[0].status, 409);
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -188,8 +203,7 @@ ...@@ -188,8 +203,7 @@
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "dropbox"
}); });
}, },
teardown: function () { teardown: function () {
...@@ -197,9 +211,9 @@ ...@@ -197,9 +211,9 @@
delete this.server; delete this.server;
} }
}); });
test("remove document", function () { test("remove document", function () {
var url_delete = "https://api.dropboxapi.com/1/fileops/delete/?" + var url_delete = "https://api.dropboxapi.com/2/files/delete_v2",
"access_token=" + token + "&root=dropbox&path=%2Fremove1%2F",
server = this.server; server = this.server;
this.server.respondWith("POST", url_delete, [204, { this.server.respondWith("POST", url_delete, [204, {
"Content-Type": "text/xml" "Content-Type": "text/xml"
...@@ -213,10 +227,13 @@ ...@@ -213,10 +227,13 @@
equal(server.requests[0].method, "POST"); equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url_delete); equal(server.requests[0].url, url_delete);
equal(server.requests[0].status, 204); equal(server.requests[0].status, 204);
equal(server.requests[0].requestBody, undefined); deepEqual(JSON.parse(server.requests[0].requestBody), {
equal(server.requests[0].responseText, ''); "path": "/remove1"
});
equal(server.requests[0].responseText, "");
deepEqual(server.requests[0].requestHeaders, { deepEqual(server.requests[0].requestHeaders, {
"Content-Type": "text/plain;charset=utf-8" "Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
}); });
}) })
.fail(function (error) { .fail(function (error) {
...@@ -275,8 +292,7 @@ ...@@ -275,8 +292,7 @@
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "dropbox"
}); });
}, },
teardown: function () { teardown: function () {
...@@ -322,6 +338,13 @@ ...@@ -322,6 +338,13 @@
}); });
test("get inexistent document", function () { test("get inexistent document", function () {
var url = "https://api.dropboxapi.com/2/files/get_metadata";
this.server.respondWith("POST", url, [409, {
"Content-Type": "application/json"
}, JSON.stringify(
{error: {'.tag': 'path', 'path': {'.tag': 'not_found'}}}
)]);
stop(); stop();
expect(3); expect(3);
...@@ -340,18 +363,25 @@ ...@@ -340,18 +363,25 @@
}); });
test("get directory", function () { test("get directory", function () {
var url = "https://api.dropboxapi.com/1/metadata/dropbox" + var url = "https://api.dropboxapi.com/2/files/get_metadata",
"/id1/?access_token=" + token; server = this.server;
this.server.respondWith("GET", url, [200, { this.server.respondWith("POST", url, [200, {
"Content-Type": "text/xml" "Content-Type": "application/json"
}, '{"is_dir": true, "contents": []}' }, '{".tag": "folder"}'
]); ]);
stop(); stop();
expect(1); expect(3);
this.jio.get("/id1/") this.jio.get("/id1/")
.then(function (result) { .then(function (result) {
deepEqual(result, {}, "Check document"); deepEqual(result, {}, "Check document");
deepEqual(JSON.parse(server.requests[0].requestBody), {
"path": "/id1"
});
deepEqual(server.requests[0].requestHeaders, {
"Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
});
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -362,11 +392,10 @@ ...@@ -362,11 +392,10 @@
}); });
test("get file", function () { test("get file", function () {
var url = "https://api.dropboxapi.com/1/metadata/dropbox" + var url = "https://api.dropboxapi.com/2/files/get_metadata";
"/id1/?access_token=" + token; this.server.respondWith("POST", url, [200, {
this.server.respondWith("GET", url, [200, { "Content-Type": "application/json"
"Content-Type": "text/xml" }, '{".tag": "file"}'
}, '{"is_dir": false, "contents": []}'
]); ]);
stop(); stop();
expect(3); expect(3);
...@@ -397,8 +426,7 @@ ...@@ -397,8 +426,7 @@
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "dropbox"
}); });
}, },
teardown: function () { teardown: function () {
...@@ -444,12 +472,14 @@ ...@@ -444,12 +472,14 @@
}); });
test("get file", function () { test("get file", function () {
var url = "https://api.dropboxapi.com/1/metadata/dropbox" + var url = "https://api.dropboxapi.com/2/files/list_folder";
"/id1/?access_token=" + token;
this.server.respondWith("GET", url, [200, { this.server.respondWith("POST", url, [409, {
"Content-Type": "text/xml" "Content-Type": "application/json"
}, '{"is_dir": false, "contents": []}' }, JSON.stringify(
]); {error: {'.tag': 'path', 'path': {'.tag': 'not_folder'}}}
)]);
stop(); stop();
expect(3); expect(3);
...@@ -468,6 +498,14 @@ ...@@ -468,6 +498,14 @@
}); });
test("get inexistent document", function () { test("get inexistent document", function () {
var url = "https://api.dropboxapi.com/2/files/list_folder";
this.server.respondWith("POST", url, [409, {
"Content-Type": "application/json"
}, JSON.stringify(
{error: {'.tag': 'path', 'path': {'.tag': 'not_found'}}}
)]);
stop(); stop();
expect(3); expect(3);
...@@ -486,18 +524,30 @@ ...@@ -486,18 +524,30 @@
}); });
test("get document without attachment", function () { test("get document without attachment", function () {
var url = "https://api.dropboxapi.com/1/metadata/dropbox" + var url = "https://api.dropboxapi.com/2/files/list_folder",
"/id1/?access_token=" + token; server = this.server;
this.server.respondWith("GET", url, [200, { this.server.respondWith("POST", url, [200, {
"Content-Type": "text/xml" "Content-Type": "application/json"
}, '{"is_dir": true, "contents": []}' }, '{"entries": [], "has_more": false}'
]); ]);
stop(); stop();
expect(1); expect(3);
this.jio.allAttachments("/id1/") this.jio.allAttachments("/id1/")
.then(function (result) { .then(function (result) {
deepEqual(result, {}, "Check document"); deepEqual(result, {}, "Check document");
deepEqual(JSON.parse(server.requests[0].requestBody), {
"include_deleted": false,
"include_has_explicit_shared_members": false,
"include_media_info": false,
"include_mounted_folders": true,
"path": "/id1",
"recursive": false
});
deepEqual(server.requests[0].requestHeaders, {
"Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
});
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -508,28 +558,26 @@ ...@@ -508,28 +558,26 @@
}); });
test("get document with attachment", function () { test("get document with attachment", function () {
var url = "https://api.dropboxapi.com/1/metadata/dropbox" + var url = "https://api.dropboxapi.com/2/files/list_folder",
"/id1/?access_token=" + token; server = this.server;
this.server.respondWith("GET", url, [200, { this.server.respondWith("POST", url, [200, {
"Content-Type": "text/xml" "Content-Type": "application/json"
}, '{"is_dir": true, "path": "/id1", ' + }, JSON.stringify({
'"contents": ' + "entries": [{
'[{"rev": "143bb45509", ' + ".tag": "file",
'"thumb_exists": false, ' + "name": "attachment1"
'"path": "/id1/attachment1", ' + }, {
'"is_dir": false, "bytes": 151}, ' + ".tag": "file",
'{"rev": "153bb45509", ' + "name": "attachment2"
'"thumb_exists": false, ' + }, {
'"path": "/id1/attachment2", ' + ".tag": "folder",
'"is_dir": false, "bytes": 11}, ' + "name": "fold1"
'{"rev": "173bb45509", ' + }],
'"thumb_exists": false, ' + "has_more": false
'"path": "/id1/fold1", ' + })]);
'"is_dir": true, "bytes": 0}], ' +
'"icon": "folder"}'
]);
stop(); stop();
expect(1); expect(3);
this.jio.allAttachments("/id1/") this.jio.allAttachments("/id1/")
.then(function (result) { .then(function (result) {
...@@ -537,6 +585,92 @@ ...@@ -537,6 +585,92 @@
attachment1: {}, attachment1: {},
attachment2: {} attachment2: {}
}, "Check document"); }, "Check document");
deepEqual(JSON.parse(server.requests[0].requestBody), {
"include_deleted": false,
"include_has_explicit_shared_members": false,
"include_media_info": false,
"include_mounted_folders": true,
"path": "/id1",
"recursive": false
});
deepEqual(server.requests[0].requestHeaders, {
"Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("get document with attachment and pagination", function () {
var url = "https://api.dropboxapi.com/2/files/list_folder",
paginate_url = "https://api.dropboxapi.com/2/files/list_folder/continue",
server = this.server,
cursor = "foocursor";
this.server.respondWith("POST", url, [200, {
"Content-Type": "application/json"
}, JSON.stringify({
"entries": [{
".tag": "file",
"name": "attachment1"
}, {
".tag": "folder",
"name": "fold1"
}],
"has_more": true,
"cursor": cursor
})]);
this.server.respondWith("POST", paginate_url, [200, {
"Content-Type": "application/json"
}, JSON.stringify({
"entries": [{
".tag": "file",
"name": "attachment2"
}, {
".tag": "folder",
"name": "fold2"
}],
"has_more": false
})]);
stop();
expect(7);
this.jio.allAttachments("/id1/")
.then(function (result) {
deepEqual(result, {
attachment1: {},
attachment2: {}
}, "Check document");
deepEqual(server.requests[0].url, url);
deepEqual(JSON.parse(server.requests[0].requestBody), {
"include_deleted": false,
"include_has_explicit_shared_members": false,
"include_media_info": false,
"include_mounted_folders": true,
"path": "/id1",
"recursive": false
});
deepEqual(server.requests[0].requestHeaders, {
"Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
});
deepEqual(server.requests[1].url, paginate_url);
deepEqual(JSON.parse(server.requests[1].requestBody), {
"cursor": cursor
});
deepEqual(server.requests[1].requestHeaders, {
"Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
});
}) })
.fail(function (error) { .fail(function (error) {
ok(false, error); ok(false, error);
...@@ -558,8 +692,7 @@ ...@@ -558,8 +692,7 @@
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "dropbox"
}); });
}, },
teardown: function () { teardown: function () {
...@@ -635,13 +768,11 @@ ...@@ -635,13 +768,11 @@
}); });
test("putAttachment document", function () { test("putAttachment document", function () {
var blob = new Blob(["foo"]), var blob = new Blob(["foo"], {"type": "xapplication/foo"}),
url_put_att = "https://content.dropboxapi.com/1/files_put/dropbox" url_put_att = "https://content.dropboxapi.com/2/files/upload",
+ "/putAttachment1/"
+ "attachment1?access_token=" + token,
server = this.server; server = this.server;
this.server.respondWith("PUT", url_put_att, [204, { this.server.respondWith("POST", url_put_att, [204, {
"Content-Type": "text/xml" "Content-Type": "text/xml"
}, ""]); }, ""]);
...@@ -656,12 +787,16 @@ ...@@ -656,12 +787,16 @@
.then(function () { .then(function () {
equal(server.requests.length, 1); equal(server.requests.length, 1);
equal(server.requests[0].method, "PUT"); equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url_put_att); equal(server.requests[0].url, url_put_att);
equal(server.requests[0].status, 204); equal(server.requests[0].status, 204);
equal(server.requests[0].responseText, ""); equal(server.requests[0].responseText, "");
deepEqual(server.requests[0].requestHeaders, { deepEqual(server.requests[0].requestHeaders, {
"Content-Type": "text/plain;charset=utf-8" "Authorization": "Bearer sample_token",
"Content-Type": "application/octet-stream;charset=utf-8",
"Dropbox-API-Arg": '{"path":"/putAttachment1/attachment1",' +
'"mode":"overwrite",' +
'"autorename":false,"mute":false}'
}); });
equal(server.requests[0].requestBody, blob); equal(server.requests[0].requestBody, blob);
}) })
...@@ -685,8 +820,7 @@ ...@@ -685,8 +820,7 @@
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "dropbox"
}); });
}, },
teardown: function () { teardown: function () {
...@@ -759,9 +893,7 @@ ...@@ -759,9 +893,7 @@
}); });
test("removeAttachment document", function () { test("removeAttachment document", function () {
var url_delete = "https://api.dropboxapi.com/1/fileops/delete/" + var url_delete = "https://api.dropboxapi.com/2/files/delete_v2",
"?access_token=" + token + "&root=dropbox" +
"&path=%2FremoveAttachment1%2Fattachment1",
server = this.server; server = this.server;
this.server.respondWith("POST", url_delete, [204, { this.server.respondWith("POST", url_delete, [204, {
...@@ -781,10 +913,13 @@ ...@@ -781,10 +913,13 @@
equal(server.requests[0].method, "POST"); equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url_delete); equal(server.requests[0].url, url_delete);
equal(server.requests[0].status, 204); equal(server.requests[0].status, 204);
equal(server.requests[0].requestBody, undefined); deepEqual(JSON.parse(server.requests[0].requestBody), {
"path": "/removeAttachment1/attachment1"
});
equal(server.requests[0].responseText, ""); equal(server.requests[0].responseText, "");
deepEqual(server.requests[0].requestHeaders, { deepEqual(server.requests[0].requestHeaders, {
"Content-Type": "text/plain;charset=utf-8" "Authorization": "Bearer sample_token",
"Content-Type": "application/json;charset=utf-8"
}); });
}) })
.fail(function (error) { .fail(function (error) {
...@@ -796,6 +931,13 @@ ...@@ -796,6 +931,13 @@
}); });
test("remove inexistent attachment", function () { test("remove inexistent attachment", function () {
var url_delete = "https://api.dropboxapi.com/2/files/delete_v2";
this.server.respondWith("POST", url_delete, [409, {
"Content-Type": "application/json"
}, JSON.stringify(
{error: {'.tag': 'path_lookup', 'path_lookup': {'.tag': 'not_found'}}}
)]);
stop(); stop();
expect(3); expect(3);
...@@ -829,8 +971,7 @@ ...@@ -829,8 +971,7 @@
this.jio = jIO.createJIO({ this.jio = jIO.createJIO({
type: "dropbox", type: "dropbox",
access_token: token, access_token: token
root : "dropbox"
}); });
}, },
teardown: function () { teardown: function () {
...@@ -903,15 +1044,14 @@ ...@@ -903,15 +1044,14 @@
}); });
test("getAttachment document", function () { test("getAttachment document", function () {
var url = "https://content.dropboxapi.com/1/files/dropbox/" + var url = "https://content.dropboxapi.com/2/files/download",
"%2FgetAttachment1%2Fattachment1?access_token=" + token,
server = this.server; server = this.server;
this.server.respondWith("GET", url, [200, { this.server.respondWith("POST", url, [200, {
"Content-Type": "text/plain" "Content-Type": "text/xplain"
}, "foo\nbaré"]); }, "foo\nbaré"]);
stop(); stop();
expect(9); expect(10);
this.jio.getAttachment( this.jio.getAttachment(
"/getAttachment1/", "/getAttachment1/",
...@@ -919,14 +1059,19 @@ ...@@ -919,14 +1059,19 @@
) )
.then(function (result) { .then(function (result) {
equal(server.requests.length, 1); equal(server.requests.length, 1);
equal(server.requests[0].method, "GET"); equal(server.requests[0].method, "POST");
equal(server.requests[0].url, url); equal(server.requests[0].url, url);
equal(server.requests[0].status, 200); equal(server.requests[0].status, 200);
equal(server.requests[0].requestBody, undefined); equal(server.requests[0].requestBody, undefined);
equal(server.requests[0].responseText, "foo\nbaré"); equal(server.requests[0].responseText, "foo\nbaré");
deepEqual(server.requests[0].requestHeaders, {
"Authorization": "Bearer sample_token",
"Content-Type": "text/plain;charset=utf-8",
"Dropbox-API-Arg": '{"path":"/getAttachment1/attachment1"}'
});
ok(result instanceof Blob, "Data is Blob"); ok(result instanceof Blob, "Data is Blob");
deepEqual(result.type, "text/plain", "Check mimetype"); deepEqual(result.type, "text/xplain", "Check mimetype");
return jIO.util.readBlobAsText(result); return jIO.util.readBlobAsText(result);
}) })
.then(function (result) { .then(function (result) {
...@@ -942,6 +1087,14 @@ ...@@ -942,6 +1087,14 @@
}); });
test("get inexistent attachment", function () { test("get inexistent attachment", function () {
var url = "https://content.dropboxapi.com/2/files/download";
this.server.respondWith("POST", url, [409, {
"Content-Type": "application/json"
}, JSON.stringify(
{error: {'.tag': 'path', 'path': {'.tag': 'not_found'}}}
)]);
stop(); stop();
expect(3); expect(3);
......
/*jslint nomen: true*/ /*jslint nomen: true*/
/*global Blob*/ /*global Blob, jiodate*/
(function (jIO, QUnit, Blob) { (function (jIO, QUnit, Blob) {
"use strict"; "use strict";
var test = QUnit.test, var test = QUnit.test,
...@@ -24,9 +24,10 @@ ...@@ -24,9 +24,10 @@
// queryStorage.constructor // queryStorage.constructor
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
module("queryStorage.constructor"); module("queryStorage.constructor");
test("create substorage", function () { test("accept parameters", function () {
var jio = jIO.createJIO({ var jio = jIO.createJIO({
type: "query", type: "query",
schema: {'date': {type: 'string', format: 'date-time'}},
sub_storage: { sub_storage: {
type: "querystorage200" type: "querystorage200"
} }
...@@ -34,9 +35,37 @@ ...@@ -34,9 +35,37 @@
ok(jio.__storage._sub_storage instanceof jio.constructor); ok(jio.__storage._sub_storage instanceof jio.constructor);
equal(jio.__storage._sub_storage.__type, "querystorage200"); equal(jio.__storage._sub_storage.__type, "querystorage200");
deepEqual(jio.__storage._key_schema.key_set, {
"date": {
"cast_to": "dateType",
"read_from": "date"
}
}, 'check key_schema');
ok(typeof jio.__storage._key_schema.cast_lookup.dateType === 'function');
}); });
test("failed on wrond schema", function () {
throws(
function () {
jIO.createJIO({
type: "query",
schema: {'date': {type: 'couscous'}},
sub_storage: {
type: "querystorage200"
}
});
},
function (error) {
ok(error instanceof jIO.util.jIOError);
equal(error.status_code, 400);
equal(error.message,
"Wrong schema for property: date");
return true;
}
);
});
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// queryStorage.get // queryStorage.get
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -823,6 +852,99 @@ ...@@ -823,6 +852,99 @@
}); });
}); });
test("manual query used and use schema", function () {
stop();
expect(4);
function StorageSchemaCapacity() {
return this;
}
StorageSchemaCapacity.prototype.get = function (id) {
var doc = {
title: id,
id: "ID " + id,
"another": "property"
};
if (id === "foo") {
equal(id, "foo", "Get foo");
doc.modification_date = "Fri, 08 Sep 2017 07:46:27 +0000";
} else {
equal(id, "bar", "Get bar");
doc.modification_date = "Thu, 07 Sep 2017 18:59:23 +0000";
}
return doc;
};
StorageSchemaCapacity.prototype.hasCapacity = function (capacity) {
if ((capacity === "list")) {
return true;
}
return false;
};
StorageSchemaCapacity.prototype.buildQuery = function (options) {
deepEqual(options, {}, "No query parameter");
var result2 = [{
id: "foo",
value: {}
}, {
id: "bar",
value: {}
}];
return result2;
};
jIO.addStorage(
'querystoragenoschemacapacity',
StorageSchemaCapacity
);
var jio = jIO.createJIO({
type: "query",
schema: {
"modification_date": {
"type": "string",
"format": "date-time"
}
},
sub_storage: {
type: "querystoragenoschemacapacity"
}
});
jio.allDocs({
sort_on: [["modification_date", "descending"]],
limit: [0, 5],
select_list: ['modification_date']
})
.then(function (result) {
deepEqual(result, {
data: {
rows: [
{
id: "foo",
doc: {},
value: {
modification_date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
}, {
id: "bar",
doc: {},
value: {
modification_date: "Thu, 07 Sep 2017 18:59:23 +0000"
}
}
],
total_rows: 2
}
});
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// queryStorage.repair // queryStorage.repair
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
} catch (e) { } catch (e) {
equal(e.name, 'TypeError', 'wrong exception type'); equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message, equal(e.message,
"SimpleQuery().create(): key_schema is not of type 'object'", "Query().create(): key_schema is not of type 'object'",
'wrong exception message'); 'wrong exception message');
} }
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
} catch (e) { } catch (e) {
equal(e.name, 'TypeError', 'wrong exception type'); equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message, equal(e.message,
"SimpleQuery().create(): key_schema has no 'key_set' property", "Query().create(): key_schema has no 'key_set' property",
'wrong exception message'); 'wrong exception message');
} }
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
} catch (e) { } catch (e) {
equal(e.name, 'TypeError', 'wrong exception type'); equal(e.name, 'TypeError', 'wrong exception type');
equal(e.message, equal(e.message,
"SimpleQuery().create(): key_schema has unknown property 'foobar'", "Query().create(): key_schema has unknown property 'foobar'",
'wrong exception message'); 'wrong exception message');
} }
......
...@@ -505,6 +505,78 @@ ...@@ -505,6 +505,78 @@
}); });
}); });
test('Query & sort_on option', function () {
var doc_list = [
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
},
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
}
];
stop();
expect(2);
jIO.QueryFactory.create("").exec(
doc_list,
{sort_on: [['date', 'descending']]}
).
then(function (list) {
var key_schema =
{
key_set: {
date: {
read_from: 'date',
cast_to: 'dateType'
}
},
cast_lookup: {
dateType: function (str) {
return window.jiodate.JIODate(new Date(str).toISOString());
}
}
};
deepEqual(list, [
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
},
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
], 'Document list is sorted');
return jIO.QueryFactory.create("", key_schema).exec(
doc_list,
{sort_on: [['date', 'ascending']]}
);
})
.then(function (list) {
deepEqual(list, [
{
identifier: 'c',
date: "Wed, 06 Sep 2017 00:27:13 +0000"
},
{
identifier: 'b',
date: "Thu, 07 Sep 2017 18:59:23 +0000"
},
{
idendifier: 'a',
date: "Fri, 08 Sep 2017 07:46:27 +0000"
}
], 'Document list is sorted with key_schema');
}).always(start);
});
// Asterisk wildcard is not supported yet. // Asterisk wildcard is not supported yet.
/* test('Full text query with asterisk', function () { /* test('Full text query with asterisk', function () {
var doc_list = [ var doc_list = [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment