Commit fd52a421 authored by Tristan Cavelier's avatar Tristan Cavelier

Merge remote-tracking branch 's3/master' into s3storage

Conflicts:
	Gruntfile.js
	Makefile
	README.md
	complex_queries.js
	examples/example.html
	examples/jio_dashboard.html
	jio.js
	package.json
	src/jio.storage/cryptstorage.js
	src/jio.storage/davstorage.js
	src/jio.storage/erp5storage.js
	src/jio.storage/gidstorage.js
	src/jio.storage/indexstorage.js
	src/jio.storage/localstorage.js
	src/jio.storage/replicaterevisionstorage.js
	src/jio.storage/replicatestorage.js
	src/jio.storage/revisionstorage.js
	src/jio.storage/s3storage.js
	src/jio.storage/xwikistorage.js
	src/jio/core/globals.js
	src/jio/core/restCommandRejecter.js
	src/jio/core/restCommandResolver.js
	src/jio/core/util.js
	src/jio/features/jobChecker.js
	src/jio/features/jobExecuter.js
	src/jio/features/jobQueue.js
	src/jio/features/jobRetry.js
	src/jio/intro.js
	test/jio.storage/davstorage.tests.js
	test/jio.storage/gidstorage.tests.js
	test/jio.storage/indexstorage.tests.js
	test/jio.storage/localstorage.tests.js
	test/jio.storage/replicaterevisionstorage.tests.js
	test/jio.storage/revisionstorage.tests.js
	test/jio.storage/s3storage.tests.js
	test/jio.storage/splitstorage.tests.js
	test/jio.storage/xwikistorage.tests.js
	test/jio/tests.js
	test/queries/tests.js
	test/run-qunit.js
	test/tests.html
	test/tests.require.js
parents 5fd24a93 a8b327e0
/*
* Copyright 2013, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/*jslint indent:2, maxlen: 80, nomen: true */
/*global jIO, define, Blob */
/**
* Provides a split storage for JIO. This storage splits data
* and store them in the sub storages defined on the description.
*
* {
* "type": "split",
* "storage_list": [<storage description>, ...]
* }
*/
// define([dependencies], module);
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO);
}(['jio'], function (jIO) {
"use strict";
/**
* Generate a new uuid
*
* @method generateUuid
* @private
* @return {String} The new uuid
*/
function generateUuid() {
function S4() {
/* 65536 */
var i, string = Math.floor(
Math.random() * 0x10000
).toString(16);
for (i = string.length; i < 4; i += 1) {
string = '0' + string;
}
return string;
}
return S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() +
S4() + S4();
}
/**
* Select a storage to put the document part
*
* @method selectStorage
* @private
* @return {Object} The selected storage
*/
function selectStorage(arg, iteration) {
var step = iteration % arg.length;
return arg[step];
}
/**
* Class to merge allDocs responses from several sub storages.
*
* @class AllDocsResponseMerger
* @constructor
*/
function AllDocsResponseMerger() {
/**
* A list of allDocs response.
*
* @attribute response_list
* @type {Array} Contains allDocs responses
* @default []
*/
this.response_list = [];
}
AllDocsResponseMerger.prototype.constructor = AllDocsResponseMerger;
/**
* Add an allDocs response to the response list.
*
* @method addResponse
* @param {Object} response The allDocs response.
* @return {AllDocsResponseMerger} This
*/
AllDocsResponseMerger.prototype.addResponse = function (response) {
this.response_list.push(response);
return this;
};
/**
* Add several allDocs responses to the response list.
*
* @method addResponseList
* @param {Array} response_list An array of allDocs responses.
* @return {AllDocsResponseMerger} This
*/
AllDocsResponseMerger.prototype.addResponseList = function (response_list) {
var i;
for (i = 0; i < response_list.length; i += 1) {
this.response_list.push(response_list[i]);
}
return this;
};
/**
* Merge the response_list to one allDocs response.
*
* The merger will find rows with the same id in order to merge them, thanks
* to the onRowToMerge method. If no row correspond to an id, rows with the
* same id will be ignored.
*
* @method merge
* @param {Object} [option={}] The merge options
* @param {Boolean} [option.include_docs=false] Tell the merger to also
* merge metadata if true.
* @return {Object} The merged allDocs response.
*/
AllDocsResponseMerger.prototype.merge = function (option) {
var result = [], row, to_merge = [], tmp, i;
if (this.response_list.length === 0) {
return [];
}
/*jslint ass: true */
while ((row = this.response_list[0].data.rows.shift()) !== undefined) {
to_merge[0] = row;
for (i = 1; i < this.response_list.length; i += 1) {
to_merge[i] = AllDocsResponseMerger.listPopFromRowId(
this.response_list[i].data.rows,
row.id
);
if (to_merge[i] === undefined) {
break;
}
}
tmp = this.onRowToMerge(to_merge, option || {});
if (tmp !== undefined) {
result[result.length] = tmp;
}
}
this.response_list = [];
return {"total_rows": result.length, "rows": result};
};
/**
* This method is called when the merger want to merge several rows with the
* same id.
*
* @method onRowToMerge
* @param {Array} row_list An array of rows.
* @param {Object} [option={}] The merge option.
* @param {Boolean} [option.include_docs=false] Also merge the metadata if
* true
* @return {Object} The merged row
*/
AllDocsResponseMerger.prototype.onRowToMerge = function (row_list, option) {
var i, k, new_row = {"value": {}}, data = "";
option = option || {};
for (i = 0; i < row_list.length; i += 1) {
new_row.id = row_list[i].id;
if (row_list[i].key) {
new_row.key = row_list[i].key;
}
if (option.include_docs) {
new_row.doc = new_row.doc || {};
for (k in row_list[i].doc) {
if (row_list[i].doc.hasOwnProperty(k)) {
if (k[0] === "_") {
new_row.doc[k] = row_list[i].doc[k];
}
}
}
data += row_list[i].doc.data;
}
}
if (option.include_docs) {
try {
data = JSON.parse(data);
} catch (e) { return undefined; }
for (k in data) {
if (data.hasOwnProperty(k)) {
new_row.doc[k] = data[k];
}
}
}
return new_row;
};
/**
* Search for a specific row and pop it. During the search operation, all
* parsed rows are stored on a dictionnary in order to be found instantly
* later.
*
* @method listPopFromRowId
* @param {Array} rows The row list
* @param {String} doc_id The document/row id
* @return {Object/undefined} The poped row
*/
AllDocsResponseMerger.listPopFromRowId = function (rows, doc_id) {
var row;
if (!rows.dict) {
rows.dict = {};
}
if (rows.dict[doc_id]) {
row = rows.dict[doc_id];
delete rows.dict[doc_id];
return row;
}
/*jslint ass: true*/
while ((row = rows.shift()) !== undefined) {
if (row.id === doc_id) {
return row;
}
rows.dict[row.id] = row;
}
};
/**
* The split storage class used by JIO.
*
* A split storage instance is able to i/o on several sub storages with
* split documents.
*
* @class SplitStorage
*/
function SplitStorage(spec) {
var that = this, priv = {};
/**
* The list of sub storages we want to use to store part of documents.
*
* @attribute storage_list
* @private
* @type {Array} Array of storage descriptions
*/
priv.storage_list = spec.storage_list;
//////////////////////////////////////////////////////////////////////
// Tools
/**
* Send a command to all sub storages. All the response are returned
* in a list. The index of the response correspond to the storage_list
* index. If an error occurs during operation, the callback is called with
* `callback(err, undefined)`. The response is given with
* `callback(undefined, response_list)`.
*
* `doc` is the document informations but can also be a list of dedicated
* document informations. In this case, each document is associated to one
* sub storage.
*
* @method send
* @private
* @param {String} method The command method
* @param {Object,Array} doc The document information to send to each sub
* storages or a list of dedicated document
* @param {Object} option The command option
* @param {Function} callback Called at the end
*/
priv.send = function (command, method, doc, option, callback) {
var i, answer_list = [], failed = false, currentServer;
function onEnd() {
i += 1;
if (i === priv.storage_list.length) {
callback(undefined, answer_list);
}
}
function onSuccess(i) {
return function (response) {
if (!failed) {
answer_list[i] = response;
}
onEnd();
};
}
function onError(i) {
return function (err) {
if (!failed) {
failed = true;
err.index = i;
callback(err, undefined);
}
};
}
if (!Array.isArray(doc)) {
for (i = 0; i < doc.length; i += 1) {
currentServer = selectStorage(priv.storage_list, i, doc.length);
if (method === 'allDocs') {
command.storage(currentServer)[method](option).
then(onSuccess(i), onError(i));
} else {
command.storage(currentServer)[method](doc, option).
then(onSuccess(i), onError(i));
}
}
} else {
for (i = 0; i < doc.length; i += 1) {
currentServer = selectStorage(priv.storage_list, i, doc.length);
// we assume that alldocs is not called if the there is several docs
command.storage(priv.storage_list[i])[method](doc[i], option).
then(onSuccess(i), onError(i));
}
}
//default splitstorage method
/*
if (!Array.isArray(doc)) {
for (i = 0; i < priv.storage_list.length; i += 1) {
if (method === 'allDocs') {
command.storage(priv.storage_list[i])[method](option).
then(onSuccess(i), onError(i));
} else {
command.storage(priv.storage_list[i])[method](doc, option).
then(onSuccess(i), onError(i));
}
}
} else {
for (i = 0; i < priv.storage_list.length; i += 1) {
// we assume that alldocs is not called if the there is several docs
command.storage(priv.storage_list[i])[method](doc[i], option).
then(onSuccess(i), onError(i));
}
}
*/
//re-init
i = 0;
};
/**
* Split document metadata then store them to the sub storages.
*
* @method postOrPut
* @private
* @param {Object} doc A serialized document object
* @param {Object} option Command option properties
* @param {String} method The command method ('post' or 'put')
*/
priv.postOrPut = function (command, doc, option, method) {
var i, data, doc_list = [], doc_underscores = {};
if (!doc._id) {
doc._id = generateUuid(); // XXX should let gidstorage guess uid
// in the future, complete id with gidstorage
}
for (i in doc) {
if (doc.hasOwnProperty(i)) {
if (i[0] === "_") {
doc_underscores[i] = doc[i];
delete doc[i];
}
}
}
data = JSON.stringify(doc);
//for (i = 0; i < priv.storage_list.length; i += 1) {
//doc_list[i] = JSON.parse(JSON.stringify(doc_underscores));
//doc_list[i].data = data.slice(
//(data.length / priv.storage_list.length) * i,
//(data.length / priv.storage_list.length) * (i + 1)
//);
//console.info('doc_list[i].data');
//console.log(doc_list[i].data);
//}
for (i = 0; i < 100; i += 1) {
doc_list[i] = JSON.parse(JSON.stringify(doc_underscores));
doc_list[i]._id = doc_list[i]._id + '_' + i;
doc_list[i].data = data.slice(
(data.length / 100) * i,
(data.length / 100) * (i + 1)
);
}
priv.send(command, method, doc_list, option, function (err) {
if (err) {
err.message = "Unable to " + method + " document";
delete err.index;
return command.error(err);
}
command.success({"id": doc_underscores._id});
});
};
//////////////////////////////////////////////////////////////////////
// JIO commands
/**
* Split document metadata then store them to the sub storages.
*
* @method post
* @param {Object} command The JIO command
*/
that.post = function (command, metadata, option) {
priv.postOrPut(command, metadata, option, 'post');
};
/**
* Split document metadata then store them to the sub storages.
*
* @method put
* @param {Object} command The JIO command
*/
that.put = function (command, metadata, option) {
priv.postOrPut(command, metadata, option, 'put');
};
/**
* Puts an attachment to the sub storages.
*
* @method putAttachment
* @param {Object} command The JIO command
*/
that.putAttachment = function (command, param, option) {
var i, attachment_list = [], data = param._blob;
for (i = 0; i < priv.storage_list.length; i += 1) {
attachment_list[i] = jIO.util.deepClone(param);
attachment_list[i]._blob = data.slice(
data.size * i / priv.storage_list.length,
data.size * (i + 1) / priv.storage_list.length,
data.type
);
}
priv.send(
command,
'putAttachment',
attachment_list,
option,
function (err) {
if (err) {
err.message = "Unable to put attachment";
delete err.index;
return command.error(err);
}
command.success();
}
);
};
/**
* Gets splited document metadata then returns real document.
*
* @method get
* @param {Object} command The JIO command
*/
that.get = function (command, param, option) {
var doc = param;
priv.send(command, 'get', doc, option, function (err, response) {
var i, k;
if (err) {
err.message = "Unable to get document";
delete err.index;
return command.error(err);
}
doc = '';
for (i = 0; i < response.length; i += 1) {
response[i] = response[i].data;
doc += response[i].data;
}
doc = JSON.parse(doc);
for (i = 0; i < response.length; i += 1) {
for (k in response[i]) {
if (response[i].hasOwnProperty(k)) {
if (k[0] === "_") {
doc[k] = response[i][k];
}
}
}
}
delete doc._attachments;
for (i = 0; i < response.length; i += 1) {
if (response[i]._attachments) {
for (k in response[i]._attachments) {
if (response[i]._attachments.hasOwnProperty(k)) {
doc._attachments = doc._attachments || {};
doc._attachments[k] = doc._attachments[k] || {
"length": 0,
"content_type": ""
};
doc._attachments[k].length += response[i]._attachments[k].
length;
// if (response[i]._attachments[k].digest) {
// if (doc._attachments[k].digest) {
// doc._attachments[k].digest += " " + response[i].
// _attachments[k].digest;
// } else {
// doc._attachments[k].digest = response[i].
// _attachments[k].digest;
// }
// }
doc._attachments[k].content_type = response[i]._attachments[k].
content_type;
}
}
}
}
command.success({"data": doc});
});
};
/**
* Gets splited document attachment then returns real attachment data.
*
* @method getAttachment
* @param {Object} command The JIO command
*/
that.getAttachment = function (command, param, option) {
priv.send(command, 'getAttachment', param, option, function (
err,
response
) {
if (err) {
err.message = "Unable to get attachment";
delete err.index;
return command.error(err);
}
command.success({"data": new Blob(response.map(function (answer) {
return answer.data;
}), {"type": response[0].data.type})});
});
};
/**
* Removes a document from the sub storages.
*
* @method remove
* @param {Object} command The JIO command
*/
that.remove = function (command, param, option) {
priv.send(
command,
'remove',
param,
option,
function (err) {
if (err) {
err.message = "Unable to remove document";
delete err.index;
return command.error(err);
}
command.success();
}
);
};
/**
* Removes an attachment from the sub storages.
*
* @method removeAttachment
* @param {Object} command The JIO command
*/
that.removeAttachment = function (command, param, option) {
priv.send(
command,
'removeAttachment',
param,
option,
function (err) {
if (err) {
err.message = "Unable to remove attachment";
delete err.index;
return command.error(err);
}
command.success();
}
);
};
/**
* Retreive a list of all document in the sub storages.
*
* If include_docs option is false, then it returns the document list from
* the first sub storage. Else, it will merge results and return.
*
* @method allDocs
* @param {Object} command The JIO command
*/
that.allDocs = function (command, param, option) {
option = {"include_docs": option.include_docs};
priv.send(
command,
'allDocs',
param,
option,
function (err, response_list) {
var all_docs_merger;
if (err) {
err.message = "Unable to retrieve document list";
delete err.index;
return command.error(err);
}
all_docs_merger = new AllDocsResponseMerger();
all_docs_merger.addResponseList(response_list);
return command.success({"data": all_docs_merger.merge(option)});
}
);
};
} // end of splitStorage
jIO.addStorage('split', SplitStorage);
}));
...@@ -16,17 +16,22 @@ ...@@ -16,17 +16,22 @@
"use strict"; "use strict";
var b64_hmac_sha1 = sha1.b64_hmac_sha1; var b64_hmac_sha1 = sha1.b64_hmac_sha1;
jIO.addStorageType("s3", function (spec, my) { jIO.addStorage("s3", function (spec) {
var that, priv = {}; var that, priv = {}, lastDigest, isDelete;
spec = spec || {}; that = this;
that = my.basicStorage(spec, my);
//nomenclature param
// param._id,
// ._attachment,
// ._blob
// attributes // attributes
priv.username = spec.username || ''; priv.username = spec.username || '';
priv.AWSIdentifier = spec.AWSIdentifier || ''; priv.AWSIdentifier = spec.AWSIdentifier || '';
priv.password = spec.password || ''; priv.password = spec.password || '';
priv.server = spec.server || ''; /*|| jiobucket ||*/ priv.server = spec.server || '';
priv.acl = spec.acl || '';
/*||> "private, /*||> "private,
public-read, public-read,
...@@ -35,8 +40,8 @@ ...@@ -35,8 +40,8 @@
bucket-owner-read, bucket-owner-read,
bucket-owner-full-control" <||*/ bucket-owner-full-control" <||*/
priv.acl = spec.acl || '';
priv.actionStatus = spec.actionStatus || ''; priv.actionStatus = spec.actionStatus || '';
priv.contenTType = spec.contenTType || ''; priv.contenTType = spec.contenTType || '';
/** /**
...@@ -255,9 +260,6 @@ ...@@ -255,9 +260,6 @@
return StringToSign; return StringToSign;
}; };
that.encodePolicy = function () { that.encodePolicy = function () {
//generates the policy //generates the policy
//enables the choice for the http response code //enables the choice for the http response code
...@@ -268,10 +270,7 @@ ...@@ -268,10 +270,7 @@
{"bucket": priv.server }, {"bucket": priv.server },
["starts-with", "$key", ""], ["starts-with", "$key", ""],
{"acl": priv.acl }, {"acl": priv.acl },
{"success_action_redirect": ""}, ["starts-with", "$Content-Type", ""]
{"success_action_status": undefined }, // http_code
["starts-with", "$Content-Type", ""],
["content-length-range", 0, 524288000]
] ]
}; };
...@@ -303,52 +302,41 @@ ...@@ -303,52 +302,41 @@
this.status === 200) { this.status === 200) {
switch (http) { switch (http) {
case "POST": case "POST":
that.success({ command.success(this.status, {id: docId});
ok: true,
id: docId
});
break; break;
case 'PUT': case 'PUT':
if (jio === true) { if (jio === true) {
that.success({ command.success(this.status);
ok: true,
id: command.getDocId()
});
} else { } else {
callback(this.responseText); callback(this.responseText);
} }
break; break;
case 'GET': case 'GET':
if (jio === true) { if (jio === true) {
if (typeof this.responseText !== 'string') {
response = JSON.parse(this.responseText);
response._attachments = response._attachments || {};
delete response._attachments;
that.success(JSON.stringify(response));
} else {
if (isAttachment === true) { if (isAttachment === true) {
that.success(this.responseText); //méthode that.getAttachment
response = this.response;
command.success(
this.status,
{'data': response, 'digest': lastDigest}
);
} else { } else {
that.success(JSON.parse(this.responseText)); // this is not an attachment
} // that.get method
response = JSON.parse(this.responseText);
command.success(this.status, {'data': response});
} }
} else { } else {
callback(this.responseText); callback(this.responseText);
} }
break; break;
case 'DELETE': case 'DELETE':
if (jio === true) { if (jio === true) {
if (isAttachment === false) { if (isAttachment === false) {
that.success({ command.success(this.status);
ok: true,
id: command.getDocId()
});
} else { } else {
that.success({ command.success(this.status);
ok: true,
id: command.getDocId(),
attachment: command.getAttachmentId()
});
} }
} else { } else {
callback(this.responseText); callback(this.responseText);
...@@ -364,7 +352,7 @@ ...@@ -364,7 +352,7 @@
//reason "reason" //reason "reason"
//message "did not work" //message "did not work"
err.error = "not_allowed"; err.error = "not_allowed";
that.error(err); command.error(err);
} }
if (this.status === 404) { if (this.status === 404) {
if (http === 'GET') { if (http === 'GET') {
...@@ -374,23 +362,36 @@ ...@@ -374,23 +362,36 @@
//error //error
//reason "reason" //reason "reason"
//message "did not work" //message "did not work"
err.statustext = "not_foud"; return command.error(
err.reason = "file does not exist"; 404,
err.error = "not_found"; "Not Found",
that.error(err); "File does not exist"
} else { );
}
//not jio
callback('404'); if (isDelete === true) {
isDelete = false;
return command.error(
404,
"Not Found",
"File does not exist"
);
} }
callback('404');
} else { } else {
//status //status
//statustext "Not Found" //statustext "Not Found"
//error //error
//reason "reason" //reason "reason"
//message "did not work" //message "did not work"
err.error = "not_found"; return command.error(
that.error(err); 404,
"Not Found",
"File does not exist"
);
} }
//fin 404
} }
if (this.status === 409) { if (this.status === 409) {
//status //status
...@@ -398,8 +399,11 @@ ...@@ -398,8 +399,11 @@
//error //error
//reason "reason" //reason "reason"
//message "did not work" //message "did not work"
err.error = "already_exists"; return command.error(
that.error(err); 409,
"Already Exists",
"File does exist"
);
} }
} }
} }
...@@ -430,30 +434,6 @@ ...@@ -430,30 +434,6 @@
return doc; return doc;
}; };
priv.createError = function (status, message, reason) {
var error = {
"status": status,
"message": message,
"reason": reason
};
switch (status) {
case 404:
error.statusText = "Not found";
break;
case 405:
error.statusText = "Method Not Allowed";
break;
case 409:
error.statusText = "Conflicts";
break;
case 24:
error.statusText = "Corrupted Document";
break;
}
error.error = error.statusText.toLowerCase().split(" ").join("_");
return error;
};
that.encodeAuthorization = function (key) { that.encodeAuthorization = function (key) {
//GET oriented method //GET oriented method
var requestUTC, httpVerb, StringToSign, Signature; var requestUTC, httpVerb, StringToSign, Signature;
...@@ -509,7 +489,13 @@ ...@@ -509,7 +489,13 @@
+ ":" + ":"
+ Signature); + Signature);
xhr.setRequestHeader("Content-Type", mime); xhr.setRequestHeader("Content-Type", mime);
if (http === 'GET' && jio === true && is_attachment === true) {
xhr.responseType = 'blob';
} else {
//défaut
xhr.responseType = 'text'; xhr.responseType = 'text';
}
xhr_onreadystatechange(docId, xhr_onreadystatechange(docId,
command, command,
...@@ -533,21 +519,20 @@ ...@@ -533,21 +519,20 @@
* @param {object} command The JIO command * @param {object} command The JIO command
**/ **/
that.post = function (command) { that.post = function (command, metadata) {
//as S3 encoding key are directly inserted within the FormData(), //as S3 encoding key are directly inserted within the FormData(),
//use of XHRwrapper function ain't pertinent //use of XHRwrapper function ain't pertinent
var doc, doc_id, mime; var doc, doc_id, mime;
doc = command.cloneDoc(); doc = metadata;
doc_id = command.getDocId(); doc_id = doc._id;
function postDocument() { function postDocument() {
var http_response, fd, Signature, xhr; var fd, Signature, xhr;
doc_id = priv.secureName(priv.idsToFileName(doc_id)); doc_id = priv.secureName(priv.idsToFileName(doc_id));
//Meant to deep-serialize in order to avoid //Meant to deep-serialize in order to avoid
//conflicts due to the multipart enctype //conflicts due to the multipart enctype
doc = JSON.stringify(doc); doc = JSON.stringify(doc);
http_response = '';
fd = new FormData(); fd = new FormData();
//virtually builds the form fields //virtually builds the form fields
//filename //filename
...@@ -559,15 +544,15 @@ ...@@ -559,15 +544,15 @@
priv.contenTType = "text/plain"; priv.contenTType = "text/plain";
fd.append('Content-Type', priv.contenTType); fd.append('Content-Type', priv.contenTType);
//allows specification of a success url redirection //allows specification of a success url redirection
fd.append('success_action_redirect', ''); //fd.append('success_action_redirect', '');
//allows to specify the http code response if the request is successful //allows to specify the http code response if the request is successful
fd.append('success_action_status', http_response); //fd.append('success_action_status', http_response);
//login AWS //login AWS
fd.append('AWSAccessKeyId', priv.AWSIdentifier); fd.append('AWSAccessKeyId', priv.AWSIdentifier);
//exchange policy with the amazon s3 service //exchange policy with the amazon s3 service
//can be common to all uploads or specific //can be common to all uploads or specific
//that.encodePolicy(fd);
that.encodePolicy(fd); that.encodePolicy(fd);
//priv.b64_policy = that.encodePolicy(fd);
fd.append('policy', priv.b64_policy); fd.append('policy', priv.b64_policy);
//signature through the base64.hmac.sha1(secret key, policy) method //signature through the base64.hmac.sha1(secret key, policy) method
Signature = b64_hmac_sha1(priv.password, priv.b64_policy); Signature = b64_hmac_sha1(priv.password, priv.b64_policy);
...@@ -594,14 +579,13 @@ ...@@ -594,14 +579,13 @@
} else { } else {
//si ce n'est pas une 404, //si ce n'est pas une 404,
//alors on renvoit une erreur 405 //alors on renvoit une erreur 405
return that.error(priv.createError( return command.error(
409, 409,
"Cannot create document", "Document already exists",
"Document already exists" "Cannot create document"
));
}
}
); );
}
});
}; };
/** /**
...@@ -610,22 +594,50 @@ ...@@ -610,22 +594,50 @@
* @param {object} command The JIO command * @param {object} command The JIO command
**/ **/
that.get = function (command) { that.get = function (command, metadata) {
var docId, attachId, isJIO, mime; var docId, isJIO, mime;
docId = command.getDocId(); docId = metadata._id;
attachId = command.getAttachmentId() || '';
isJIO = true; isJIO = true;
mime = 'text/plain; charset=UTF-8'; mime = 'text/plain; charset=UTF-8';
that.XHRwrapper(command, docId, attachId, 'GET', mime, '', isJIO, false); that.XHRwrapper(command, docId, '', 'GET', mime, '', isJIO, false);
}; };
that.getAttachment = function (command) { that.getAttachment = function (command, param) {
var docId, attachId, isJIO, mime; var docId, attachId, isJIO, mime;
docId = command.getDocId();
attachId = command.getAttachmentId(); function getTheAttachment() {
docId = param._id;
attachId = param._attachment;
isJIO = true; isJIO = true;
mime = 'text/plain; charset=UTF-8'; mime = 'text/plain; charset=UTF-8';
that.XHRwrapper(command, docId, attachId, 'GET', mime, '', isJIO, true); that.XHRwrapper(command, docId, attachId, 'GET', mime, '', isJIO, true);
}
function getDoc() {
docId = param._id;
isJIO = false;
mime = 'text/plain; charset=UTF-8';
that.XHRwrapper(command, docId, '', 'GET', mime, '', isJIO, false,
function (response) {
var responseObj = JSON.parse(response)._attachments;
if (responseObj !== undefined) {
if (responseObj[param._attachment] !== undefined) {
lastDigest = JSON.parse(response).
_attachments[param._attachment].digest;
}
}
getTheAttachment();
});
}
getDoc();
//docId = param._id;
//attachId = param._attachment;
//isJIO = true;
//mime = 'text/plain; charset=UTF-8';
//that.XHRwrapper(command, docId, attachId, 'GET', mime,
// '', isJIO, true);
}; };
/** /**
...@@ -634,10 +646,10 @@ ...@@ -634,10 +646,10 @@
* @param {object} command The JIO command * @param {object} command The JIO command
**/ **/
that.put = function (command) { that.put = function (command, metadata) {
var doc, docId, mime; var doc, docId, mime;
doc = command.cloneDoc(); doc = metadata;
docId = command.getDocId(); docId = doc._id;
mime = 'text/plain; charset=UTF-8'; mime = 'text/plain; charset=UTF-8';
//pas d'attachment dans un put simple //pas d'attachment dans un put simple
function putDocument() { function putDocument() {
...@@ -657,39 +669,41 @@ ...@@ -657,39 +669,41 @@
that.XHRwrapper(command, docId, '', 'GET', mime, '', false, false, that.XHRwrapper(command, docId, '', 'GET', mime, '', false, false,
function (response) { function (response) {
//if (response === '404') {} var responseObj = JSON.parse(response);
if (response._attachments !== undefined) {
doc._attachments = response._attachments; if (responseObj._attachments !== undefined) {
doc._attachments = responseObj._attachments;
} }
putDocument(); putDocument();
} // XXX control non existing document to throw a 201 http code
); });
}; };
that.putAttachment = function (command) { that.putAttachment = function (command, param) {
var mon_document, var my_document,
docId, docId,
attachId, attachId,
mime, mime,
attachment_data, attachment_data,
attachment_md5, attachment_digest,
attachment_mimetype, attachment_mimetype,
attachment_length; attachment_length;
mon_document = null; my_document = null;
docId = command.getDocId(); docId = param._id;
attachId = command.getAttachmentId() || ''; attachId = param._attachment;
mime = 'text/plain; charset=UTF-8'; mime = param._blob.type;
//récupération des variables de l'attachement
//attachment_id = command.getAttachmentId(); attachment_data = param._blob;
attachment_data = command.getAttachmentData();
attachment_md5 = command.md5SumAttachmentData(); jIO.util.readBlobAsBinaryString(param._blob).then(function (e) {
attachment_mimetype = command.getAttachmentMimeType(); var binary_string = e.target.result;
attachment_length = command.getAttachmentLength(); attachment_digest = jIO.util.makeBinaryStringDigest(binary_string);
function putAttachment() { function putAttachment() {
that.XHRwrapper(command, that.XHRwrapper(
command,
docId, docId,
attachId, attachId,
'PUT', 'PUT',
...@@ -698,12 +712,9 @@ ...@@ -698,12 +712,9 @@
false, false,
true, true,
function () { function () {
that.success({ command.success({
// response // response
"ok": true, "digest": attachment_digest
"id": docId,
"attachment": attachId
//"rev": current_revision
}); });
} }
); );
...@@ -711,40 +722,42 @@ ...@@ -711,40 +722,42 @@
function putDocument() { function putDocument() {
var attachment_obj, data, doc; var attachment_obj, data, doc;
attachment_mimetype = param._blob.type;
attachment_length = param._blob.size;
attachment_obj = { attachment_obj = {
//"revpos": 3, // optional //"revpos": 3, // optional
"digest": attachment_md5, "digest": attachment_digest,
"content_type": attachment_mimetype, "content_type": attachment_mimetype,
"length": attachment_length "length": attachment_length
}; };
data = JSON.parse(mon_document);
data = JSON.parse(my_document);
doc = priv.updateMeta(data, docId, attachId, "add", attachment_obj); doc = priv.updateMeta(data, docId, attachId, "add", attachment_obj);
that.XHRwrapper(command, docId, '', 'PUT', mime, doc, false, false, that.XHRwrapper(command, docId, '', 'PUT', mime, doc, false, false,
function () { function () {
putAttachment(); putAttachment();
} });
);
} }
function getDocument() { function getDocument() {
//XHRwrapper(command,'PUT','text/plain; charset=UTF-8',true);
that.XHRwrapper(command, docId, '', 'GET', mime, '', false, false, that.XHRwrapper(command, docId, '', 'GET', mime, '', false, false,
function (reponse) { function (response) {
if (reponse === '404') { if (response === '404') {
return that.error(priv.createError( return command.error(
404, 404,
"Cannot find document", "Document does not exist",
"Document does not exist" "Cannot find document"
)); );
} }
mon_document = reponse; my_document = response;
putDocument(); putDocument();
} });
);
} }
getDocument(); getDocument();
});
}; };
/** /**
...@@ -753,15 +766,16 @@ ...@@ -753,15 +766,16 @@
* @param {object} command The JIO command * @param {object} command The JIO command
*/ */
that.remove = function (command) { that.remove = function (command, param) {
var docId, mime; var docId, mime;
docId = command.getDocId(); docId = param._id;
mime = 'text/plain; charset=UTF-8'; mime = 'text/plain; charset=UTF-8';
isDelete = true;
function deleteDocument() { function deleteDocument() {
isDelete = false;
that.XHRwrapper(command, docId, '', 'DELETE', mime, '', true, false, that.XHRwrapper(command, docId, '', 'DELETE', mime, '', true, false,
function () { function () {
that.success({ command.success({
// response // response
"ok": true, "ok": true,
"id": docId "id": docId
...@@ -798,23 +812,23 @@ ...@@ -798,23 +812,23 @@
); );
}; };
that.removeAttachment = function (command) { that.removeAttachment = function (command, param) {
var mon_document, var my_document,
docId, docId,
attachId, attachId,
mime; mime;
mon_document = null; my_document = null;
docId = command.getDocId(); docId = param._id;
attachId = command.getAttachmentId() || ''; attachId = param._attachment;
mime = 'text/plain; charset=UTF-8'; mime = 'text/plain; charset=UTF-8';
//récupération des variables de l'attachement //récupération des variables de l'attachement
// attachment_id = command.getAttachmentId(); //attachment_id = command.getAttachmentId();
// attachment_data = command.getAttachmentData(); //attachment_data = command.getAttachmentData();
// attachment_md5 = command.md5SumAttachmentData(); //attachment_md5 = command.md5SumAttachmentData();
// attachment_mimetype = command.getAttachmentMimeType(); //attachment_mimetype = command.getAttachmentMimeType();
// attachment_length = command.getAttachmentLength(); //attachment_length = command.getAttachmentLength();
function removeAttachment() { function removeAttachment() {
that.XHRwrapper(command, docId, attachId, 'DELETE', mime, '', true, that.XHRwrapper(command, docId, attachId, 'DELETE', mime, '', true,
...@@ -825,7 +839,8 @@ ...@@ -825,7 +839,8 @@
function putDocument() { function putDocument() {
var data, doc; var data, doc;
data = JSON.parse(mon_document); //data = JSON.parse(my_document);
data = my_document;
doc = priv.updateMeta(data, docId, attachId, "remove", ''); doc = priv.updateMeta(data, docId, attachId, "remove", '');
that.XHRwrapper(command, docId, '', 'PUT', mime, doc, that.XHRwrapper(command, docId, '', 'PUT', mime, doc,
false, false, function () { false, false, function () {
...@@ -835,12 +850,33 @@ ...@@ -835,12 +850,33 @@
function getDocument() { function getDocument() {
that.XHRwrapper(command, docId, '', 'GET', mime, '', false, false, that.XHRwrapper(command, docId, '', 'GET', mime, '', false, false,
function (reponse) { function (response) {
mon_document = reponse; if (response === '404') {
putDocument(); return command.error(
404,
"missing document",
"This Document does not exist"
);
} }
my_document = JSON.parse(response);
if (my_document._attachments === undefined) {
return command.error(
404,
"missing attachment",
"This Document has no attachments"
);
}
if (my_document._attachments[attachId] !== undefined) {
putDocument();
} else {
return command.error(
404,
"missing attachment",
"This Attachment does not exist"
); );
} }
});
}
getDocument(); getDocument();
}; };
...@@ -850,9 +886,10 @@ ...@@ -850,9 +886,10 @@
* @param {object} command The JIO command * @param {object} command The JIO command
**/ **/
that.allDocs = function (command) { that.allDocs = function (command, param, options) {
var mon_document, mime; /*jslint unparam: true */
mon_document = null; var my_document, mime;
my_document = null;
mime = 'text/plain; charset=UTF-8'; mime = 'text/plain; charset=UTF-8';
function makeJSON() { function makeJSON() {
...@@ -870,7 +907,7 @@ ...@@ -870,7 +907,7 @@
callURL, callURL,
requestUTC; requestUTC;
keys = $(mon_document).find('Key'); keys = $(my_document).find('Key');
resultTable = []; resultTable = [];
counter = 0; counter = 0;
...@@ -892,7 +929,6 @@ ...@@ -892,7 +929,6 @@
allDocResponse = { allDocResponse = {
// document content will be added to response // document content will be added to response
"total_rows": resultTable.length, "total_rows": resultTable.length,
"offset": 0,
"rows": [] "rows": []
}; };
...@@ -905,7 +941,7 @@ ...@@ -905,7 +941,7 @@
return function (doc, statustext, response) { return function (doc, statustext, response) {
allDoc.rows[i].doc = response.responseText; allDoc.rows[i].doc = response.responseText;
if (count === 0) { if (count === 0) {
that.success(allDoc); command.success(allDoc);
} else { } else {
count -= 1; count -= 1;
} }
...@@ -914,13 +950,8 @@ ...@@ -914,13 +950,8 @@
errCallback = function (err) { errCallback = function (err) {
if (err.status === 404) { if (err.status === 404) {
//status
//statustext "Not Found"
//error
//reason "reason"
//message "did not work"
err.error = "not_found"; err.error = "not_found";
that.error(err); command.error(err);
} else { } else {
return that.retry(err); return that.retry(err);
} }
...@@ -928,20 +959,16 @@ ...@@ -928,20 +959,16 @@
i = resultTable.length - 1; i = resultTable.length - 1;
if (command.getOption("include_docs") === true) { if (options.include_docs) {
for (i; i >= 0; i -= 1) { for (i; i >= 0; i -= 1) {
keyId = resultTable[i]; keyId = resultTable[i];
Signature = that.encodeAuthorization(keyId); Signature = that.encodeAuthorization(keyId);
callURL = 'http://' + priv.server + '.s3.amazonaws.com/' + keyId; callURL = 'http://' + priv.server + '.s3.amazonaws.com/' + keyId;
requestUTC = new Date().toUTCString(); requestUTC = new Date().toUTCString();
allDocResponse.rows[i] = { allDocResponse.rows[i] = {
"id": priv.fileNameToIds(keyId).join(), "id": priv.fileNameToIds(keyId).join(),
"key": keyId,
"value": {} "value": {}
}; };
$.ajax({ $.ajax({
contentType : '', contentType : '',
crossdomain : true, crossdomain : true,
...@@ -961,7 +988,7 @@ ...@@ -961,7 +988,7 @@
//'x-amz-security-token' : , //'x-amz-security-token' : ,
}, },
success : dealCallback(i, countB, allDocResponse), success : dealCallback(i, countB, allDocResponse),
error : errCallback(that.error) error : errCallback(command.error)
}); });
countB += 1; countB += 1;
} }
...@@ -970,11 +997,11 @@ ...@@ -970,11 +997,11 @@
keyId = resultTable[i]; keyId = resultTable[i];
allDocResponse.rows[i] = { allDocResponse.rows[i] = {
"id": priv.fileNameToIds(keyId).join(), "id": priv.fileNameToIds(keyId).join(),
"key": keyId,
"value": {} "value": {}
}; };
} }
that.success(allDocResponse); allDocResponse = {"data": allDocResponse};
command.success(allDocResponse);
} }
} }
...@@ -982,16 +1009,13 @@ ...@@ -982,16 +1009,13 @@
//XHRwrapper(command,'PUT','text/plain; charset=UTF-8',true); //XHRwrapper(command,'PUT','text/plain; charset=UTF-8',true);
that.XHRwrapper(command, '', '', 'GET', mime, '', false, false, that.XHRwrapper(command, '', '', 'GET', mime, '', false, false,
function (reponse) { function (reponse) {
mon_document = reponse; my_document = reponse;
makeJSON(); makeJSON();
} }
); );
} }
getXML(); getXML();
//fin alldocs //fin alldocs
}; };
return that;
}); });
})); }));
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO, test_util, RSVP, test, ok, deepEqual, module, stop,
start, hex_sha256 */
// define([module_name], [dependencies], module);
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO, test_util, RSVP);
}([
'jio',
'test_util',
'rsvp',
'localstorage',
'splitstorage'
], function (jIO, util, RSVP) {
"use strict";
var tool = {
"readBlobAsBinaryString": jIO.util.readBlobAsBinaryString
};
function reverse(promise) {
return new RSVP.Promise(function (resolve, reject, notify) {
promise.then(reject, resolve, notify);
}, function () {
promise.cancel();
});
}
/**
* sequence(thens): Promise
*
* Executes a sequence of *then* callbacks. It acts like
* `smth().then(callback).then(callback)...`. The first callback is called
* with no parameter.
*
* Elements of `thens` array can be a function or an array contaning at most
* three *then* callbacks: *onFulfilled*, *onRejected*, *onNotified*.
*
* When `cancel()` is executed, each then promises are cancelled at the same
* time.
*
* @param {Array} thens An array of *then* callbacks
* @return {Promise} A new promise
*/
function sequence(thens) {
var promises = [];
return new RSVP.Promise(function (resolve, reject, notify) {
var i;
promises[0] = new RSVP.Promise(function (resolve) {
resolve();
});
for (i = 0; i < thens.length; i += 1) {
if (Array.isArray(thens[i])) {
promises[i + 1] = promises[i].
then(thens[i][0], thens[i][1], thens[i][2]);
} else {
promises[i + 1] = promises[i].then(thens[i]);
}
}
promises[i].then(resolve, reject, notify);
}, function () {
var i;
for (i = 0; i < promises.length; i += 1) {
promises[i].cancel();
}
});
}
function unexpectedError(error) {
if (error instanceof Error) {
deepEqual([
error.name + ": " + error.message,
error
], "UNEXPECTED ERROR", "Unexpected error");
} else {
deepEqual(error, "UNEXPECTED ERROR", "Unexpected error");
}
}
module("SplitStorage + LocalStorage");
test("Post", function () {
var shared = {}, jio, jio_local_list = [];
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "post1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "post2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
jio_local_list[0] = jIO.createJIO(shared.local_storage_description1, {
"workspace": shared.workspace
});
jio_local_list[1] = jIO.createJIO(shared.local_storage_description2, {
"workspace": shared.workspace
});
jio_local_list.run = function (method, argument) {
var i, promises = [];
for (i = 0; i < this.length; i += 1) {
promises[i] = this[i][method].apply(this[i], argument);
}
return RSVP.all(promises);
};
jio_local_list.get = function () {
return this.run("get", arguments);
};
stop();
// post without id
jio.post({
"_underscored_meta": "uvalue",
"meta": "data"
}).then(function (answer) {
shared.uuid = answer.id;
answer.id = "<uuid>";
ok(util.isUuid(shared.uuid), "Uuid should look like " +
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx : " + shared.uuid);
deepEqual(answer, {
"id": "<uuid>",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document without id");
// check uploaded documents
return jio_local_list.get({"_id": shared.uuid});
}).then(function (answers) {
var i;
for (i = 0; i < answers.length; i += 1) {
deepEqual(answers[i].data, {
"_id": shared.uuid,
"_underscored_meta": "uvalue",
"data": i === 0 ? "{\"meta\"" : ":\"data\"}"
}, "Check uploaded document in sub storage " + (i + 1));
}
// post with id
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
});
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document with id");
// check uploaded documents
return jio_local_list.get({"_id": "one"});
}).then(function (answers) {
deepEqual(answers[0].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "{\"meta\":\"data\","
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "\"hello\":\"world\"}"
}, "Check uploaded document in sub storage 2");
// post with id
return reverse(jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
}));
}).then(function (answer) {
deepEqual(answer, {
"error": "conflict",
"id": "one",
"message": "Unable to post document",
"method": "post",
"reason": "document exists",
"result": "error",
"status": 409,
"statusText": "Conflict"
}, "Post document with same id -> 409 Conflict");
}).fail(unexpectedError).always(start);
});
test("PutAttachment", function () {
var shared = {}, jio, jio_local_list = [];
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "putAttachment1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "putAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
jio_local_list[0] = jIO.createJIO(shared.local_storage_description1, {
"workspace": shared.workspace
});
jio_local_list[1] = jIO.createJIO(shared.local_storage_description2, {
"workspace": shared.workspace
});
jio_local_list.run = function (method, argument) {
var i, promises = [];
for (i = 0; i < this.length; i += 1) {
promises[i] = this[i][method].apply(this[i], argument);
}
return RSVP.all(promises);
};
jio_local_list.get = function () {
return this.run("get", arguments);
};
jio_local_list.getAttachmentAsBinaryString = function () {
return this.run("getAttachment", arguments).then(function (answers) {
var i, promises = [];
for (i = 0; i < answers.length; i += 1) {
promises[i] = tool.readBlobAsBinaryString(answers[i].data);
}
return RSVP.all(promises);
});
};
stop();
return reverse(jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to put attachment",
"method": "putAttachment",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Put attachment on a inexistent document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "one",
"method": "putAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put attachment on a document");
// check uploaded documents
return jio_local_list.get({"_id": "one"});
}).then(function (answers) {
deepEqual(answers[0].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-ebf2d770a6a2dfa135f6c81431f22fc3cbcde9ae" +
"e52759ca9e520d4d964c1322", // sha256("My ")
"length": 3
}
},
"_id": "one",
"_underscored_meta": "uvalue",
"data": "{\"meta\""
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-cec3a9b89b2e391393d0f68e4bc12a9fa6cf358b" +
"3cdf79496dc442d52b8dd528", // sha256("Data")
"length": 4
}
},
"_id": "one",
"_underscored_meta": "uvalue",
"data": ":\"data\"}"
}, "Check uploaded document in sub storage 2");
return jio_local_list.getAttachmentAsBinaryString({
"_id": "one",
"_attachment": "my_attachment"
});
}).then(function (events) {
deepEqual(events[0].target.result, "My ",
"Check uploaded document in sub storage 1");
deepEqual(events[1].target.result, "Data",
"Check uploaded document in sub storage 1");
}).fail(unexpectedError).always(start);
});
test("Get", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "get1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "get2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.get({"_id": "one"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "one",
"message": "Unable to get document",
"method": "get",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing document");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Get posted document");
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
});
}).then(function () {
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"_attachments": {
"my_attachment": {
"length": 7,
"content_type": "text/plain"
}
}
}, "Get document with attachment informations");
}).fail(unexpectedError).always(start);
});
test("GetAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "getAttachment1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "getAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get attachment from missing document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing attachment from document");
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.getAttachment({"_id": "one", "_attachment": "my_attachment"});
}).then(function (answer) {
return tool.readBlobAsBinaryString(answer.data);
}).then(function (event) {
deepEqual(event.target.result, "My Data", "Get attachment");
}).fail(unexpectedError).always(start);
});
test("RemoveAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "removeAttachment1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "removeAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.removeAttachment({
"_id": "one",
"_attachment": "my_attachment"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove attachment from inexistent document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return reverse(jio.removeAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove inexistent attachment -> 404 Not Found");
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.removeAttachment({
"_id": "one",
"_attachment": "my_attachment"
});
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "one",
"method": "removeAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove attachment");
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
}).fail(unexpectedError).always(start);
});
test("Remove", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "remove1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "remove2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.remove({"_id": "one"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "one",
"message": "Unable to remove document",
"method": "remove",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove missing document -> 404 Not Found");
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "one",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.remove({"_id": "one"});
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "remove",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove document");
return reverse(jio.getAttachment({
"_id": "one",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "one",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
return reverse(jio.get({"_id": "one"}));
}).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "one",
"message": "Unable to get document",
"method": "get",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check document -> 404 Not Found");
}).fail(unexpectedError).always(start);
});
test("Put", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "put1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "put2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
jio.put({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put new document");
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return jio.put({
"_id": "one",
"_underscored_meta": "uvalue",
"meow": "dog"
});
}).then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put same document again");
return jio.get({"_id": "one"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "one",
"_underscored_meta": "uvalue",
"meow": "dog"
}, "Get document for check");
}).fail(unexpectedError).always(start);
});
test("AllDocs", function () {
var shared = {}, jio;
shared.workspace = {};
shared.local_storage_description1 = {
"type": "local",
"username": "splitstorage",
"application_name": "alldocs1",
"mode": "memory"
};
shared.local_storage_description2 = {
"type": "local",
"username": "splitstorage",
"application_name": "alldocs2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.local_storage_description1,
shared.local_storage_description2
]
}, {"workspace": shared.workspace});
stop();
function prepareDatabase() {
var i, do_list = [];
function post(i) {
return function () {
return jio.post({
"_id": "doc" + i,
"_underscored_meta": "uvalue" + i,
"meta": "data" + i
});
};
}
function putAttachment(i) {
return function () {
return jio.putAttachment({
"_id": "doc" + i,
"_attachment": "my_attachment" + i,
"_data": "My Data" + i,
"_content_type": "text/plain"
});
};
}
for (i = 0; i < 5; i += 1) {
do_list.push(post(i));
}
for (i = 0; i < 2; i += 1) {
do_list.push(putAttachment(i));
}
return sequence(do_list);
}
prepareDatabase().then(function () {
return jio.get({"_id": "doc1"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "doc1",
"_underscored_meta": "uvalue1",
"meta": "data1",
"_attachments": {
"my_attachment1": {
"length": 8,
"content_type": "text/plain"
}
}
}, "Check document");
return jio.allDocs();
}).then(function (answer) {
answer.data.rows.sort(function (a, b) {
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
});
deepEqual(answer.data, {
"total_rows": 5,
"rows": [{
"id": "doc0",
"key": "doc0",
"value": {}
}, {
"id": "doc1",
"key": "doc1",
"value": {}
}, {
"id": "doc2",
"key": "doc2",
"value": {}
}, {
"id": "doc3",
"key": "doc3",
"value": {}
}, {
"id": "doc4",
"key": "doc4",
"value": {}
}]
}, "AllDocs with document ids only");
}).fail(unexpectedError).always(start);
});
}));
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO, test_util, RSVP, test, ok, deepEqual, module, stop,
start, hex_sha256 */
// define([module_name], [dependencies], module);
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO, test_util, RSVP);
}([
'jio',
'test_util',
'rsvp',
's3storage',
'multisplitstorage'
], function (jIO, util, RSVP) {
"use strict";
var tool = {
"readBlobAsBinaryString": jIO.util.readBlobAsBinaryString
};
function reverse(promise) {
return new RSVP.Promise(function (resolve, reject, notify) {
promise.then(reject, resolve, notify);
}, function () {
promise.cancel();
});
}
/**
* sequence(thens): Promise
*
* Executes a sequence of *then* callbacks. It acts like
* `smth().then(callback).then(callback)...`. The first callback is called
* with no parameter.
*
* Elements of `thens` array can be a function or an array contaning at most
* three *then* callbacks: *onFulfilled*, *onRejected*, *onNotified*.
*
* When `cancel()` is executed, each then promises are cancelled at the same
* time.
*
* @param {Array} thens An array of *then* callbacks
* @return {Promise} A new promise
*/
function sequence(thens) {
var promises = [];
return new RSVP.Promise(function (resolve, reject, notify) {
var i;
promises[0] = new RSVP.Promise(function (resolve) {
resolve();
});
for (i = 0; i < thens.length; i += 1) {
if (Array.isArray(thens[i])) {
promises[i + 1] = promises[i].
then(thens[i][0], thens[i][1], thens[i][2]);
} else {
promises[i + 1] = promises[i].then(thens[i]);
}
}
promises[i].then(resolve, reject, notify);
}, function () {
var i;
for (i = 0; i < promises.length; i += 1) {
promises[i].cancel();
}
});
}
function unexpectedError(error) {
if (error instanceof Error) {
deepEqual([
error.name + ": " + error.message,
error
], "UNEXPECTED ERROR", "Unexpected error");
} else {
deepEqual(error, "UNEXPECTED ERROR", "Unexpected error");
}
}
module("SplitStorage + S3 Storage");
test("Post", function () {
var shared = {}, jio, jio_s3_list = [];
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
jio_s3_list[0] = jIO.createJIO(shared.s3_storage_description1, {
"workspace": shared.workspace
});
jio_s3_list[1] = jIO.createJIO(shared.s3_storage_description2, {
"workspace": shared.workspace
});
jio_s3_list.run = function (method, argument) {
var i, promises = [];
for (i = 0; i < this.length; i += 1) {
promises[i] = this[i][method].apply(this[i], argument);
}
return RSVP.all(promises);
};
jio_s3_list.get = function () {
return this.run("get", arguments);
};
stop();
// post without id
jio.post({
"_underscored_meta": "uvalue",
"meta": "data"
})
.then(function (answer) {
shared.uuid = answer.id;
answer.id = "<uuid>";
ok(util.isUuid(shared.uuid), "Uuid should look like " +
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx : " + shared.uuid);
deepEqual(answer, {
"id": "<uuid>",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document without id");
// check uploaded documents
return jio_s3_list.get({"_id": shared.uuid});
})
.then(function (answers) {
var i;
for (i = 0; i < answers.length; i += 1) {
deepEqual(answers[i].data, {
"_id": shared.uuid,
"_underscored_meta": "uvalue",
"data": i === 0 ? "{\"meta\"" : ":\"data\"}"
}, "Check uploaded document in sub storage " + (i + 1));
}
// post with id
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
});
})
.then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document with id");
// check uploaded documents
return jio_s3_list.get({"_id": "one"});
})
.then(function (answers) {
deepEqual(answers[0].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "{\"meta\":\"data\","
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "\"hello\":\"world\"}"
}, "Check uploaded document in sub storage 2");
// post with id
return reverse(jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
}));
})
.then(function (answer) {
deepEqual(answer, {
"error": "conflict",
"id": "one",
"message": "Unable to post document",
"method": "post",
"reason": "Document already exists",
"result": "error",
"status": 409,
"statusText": "Conflict"
}, "Post document with same id -> 409 Conflict");
})
.fail(unexpectedError).always(start);
});
/*
test("PutAttachment", function () {
var shared = {}, jio, jio_s3_list = [];
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "putAttachment1",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "putAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
jio_s3_list[0] = jIO.createJIO(shared.s3_storage_description1, {
"workspace": shared.workspace
});
jio_s3_list[1] = jIO.createJIO(shared.s3_storage_description2, {
"workspace": shared.workspace
});
jio_s3_list.run = function (method, argument) {
var i, promises = [];
for (i = 0; i < this.length; i += 1) {
promises[i] = this[i][method].apply(this[i], argument);
}
return RSVP.all(promises);
};
jio_s3_list.get = function () {
return this.run("get", arguments);
};
jio_s3_list.getAttachmentAsBinaryString = function () {
return this.run("getAttachment", arguments).then(function (answers) {
var i, promises = [];
for (i = 0; i < answers.length; i += 1) {
promises[i] = tool.readBlobAsBinaryString(answers[i].data);
}
return RSVP.all(promises);
});
};
stop();
return reverse(jio.putAttachment({
"_id": "two",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "two",
"message": "Unable to put attachment",
"method": "putAttachment",
"reason": "Document does not exist",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Put attachment on a inexistent document -> 404 Not Found");
return jio.post({
"_id": "two",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "two",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "two",
"method": "putAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put attachment on a document");
// check uploaded documents
return jio_s3_list.get({"_id": "two"});
}).then(function (answers) {
deepEqual(answers[0].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-ebf2d770a6a2dfa135f6c81431f22fc3cbcde9ae" +
"e52759ca9e520d4d964c1322", // sha256("My ")
"length": 3
}
},
"_id": "two",
"_underscored_meta": "uvalue",
"data": "{\"meta\""
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-cec3a9b89b2e391393d0f68e4bc12a9fa6cf358b" +
"3cdf79496dc442d52b8dd528", // sha256("Data")
"length": 4
}
},
"_id": "two",
"_underscored_meta": "uvalue",
"data": ":\"data\"}"
}, "Check uploaded document in sub storage 2");
return jio_s3_list.getAttachmentAsBinaryString({
"_id": "two",
"_attachment": "my_attachment"
});
}).then(function (events) {
deepEqual(events[0].target.result, "My ",
"Check uploaded document in sub storage 1");
deepEqual(events[1].target.result, "Data",
"Check uploaded document in sub storage 1");
}).fail(unexpectedError).always(start);
});
*/
/*
test("Get", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "get1",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "get2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.get({"_id": "three"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "three",
"message": "Unable to get document",
"method": "get",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing document");
return jio.post({
"_id": "three",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.get({"_id": "three"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "three",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Get posted document");
return jio.putAttachment({
"_id": "three",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
});
}).then(function () {
return jio.get({"_id": "three"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "three",
"_underscored_meta": "uvalue",
"meta": "data",
"_attachments": {
"my_attachment": {
"length": 7,
"content_type": "text/plain"
}
}
}, "Get document with attachment informations");
}).fail(unexpectedError).always(start);
});
*/
/*
test("GetAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "getAttachment",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "getAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.getAttachment({
"_id": "four",
"_attachment": "my_attachment"
}))
.then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "four",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get attachment from missing document -> 404 Not Found");
return jio.post({
"_id": "four",
"_underscored_meta": "uvalue",
"meta": "data"
});
})
.then(function () {
return reverse(jio.getAttachment({
"_id": "four",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "four",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing attachment from document");
return jio.putAttachment({
"_id": "four",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
})
.then(function () {
return jio.getAttachment({
"_id": "four",
"_attachment": "my_attachment"
});
}).then(function (answer) {
return tool.readBlobAsBinaryString(answer.data);
}).then(function (event) {
deepEqual(event.target.result, "My Data", "Get attachment");
})
.fail(unexpectedError).always(start);
});
*/
/*
test("RemoveAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.removeAttachment({
"_id": "five",
"_attachment": "my_attachment"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "five",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove attachment from inexistent document -> 404 Not Found");
return jio.post({
"_id": "five",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return reverse(jio.removeAttachment({
"_id": "five",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "five",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove inexistent attachment -> 404 Not Found");
return jio.putAttachment({
"_id": "five",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
})
.then(function () {
return jio.removeAttachment({
"_id": "five",
"_attachment": "my_attachment"
});
})
.then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "five",
"method": "removeAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove attachment");
return jio.get({"_id": "five"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "five",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return reverse(jio.getAttachment({
"_id": "five",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "five",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
})
.fail(unexpectedError).always(start);
});
*/
/*
test("Remove", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.remove({"_id": "six"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "six",
"message": "Unable to remove document",
"method": "remove",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove missing document -> 404 Not Found");
return jio.post({
"_id": "six",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "six",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.remove({"_id": "six"});
}).then(function (answer) {
deepEqual(answer, {
"id": "six",
"method": "remove",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove document");
return reverse(jio.getAttachment({
"_id": "six",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "six",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
return reverse(jio.get({"_id": "six"}));
}).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "six",
"message": "Unable to get document",
"method": "get",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check document -> 404 Not Found");
}).fail(unexpectedError).always(start);
});
*/
/*
test("Put", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
jio.put({
"_id": "seven",
"_underscored_meta": "uvalue",
"meta": "data"
}).then(function (answer) {
deepEqual(answer, {
"id": "seven",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put new document");
return jio.get({"_id": "seven"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "seven",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return jio.put({
"_id": "seven",
"_underscored_meta": "uvalue",
"meow": "dog"
});
}).then(function (answer) {
deepEqual(answer, {
"id": "seven",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put same document again");
return jio.get({"_id": "seven"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "seven",
"_underscored_meta": "uvalue",
"meow": "dog"
}, "Get document for check");
}).fail(unexpectedError).always(start);
});
*/
/*
test("AllDocs", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucket_alldocs",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucket_alldocs_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
function prepareDatabase() {
var i, do_list = [];
function post(i) {
return function () {
return jio.post({
"_id": "doc" + i,
"_underscored_meta": "uvalue" + i,
"meta": "data" + i
});
};
}
function putAttachment(i) {
return function () {
return jio.putAttachment({
"_id": "doc" + i,
"_attachment": "my_attachment" + i,
"_data": "My Data" + i,
"_content_type": "text/plain"
});
};
}
for (i = 0; i < 5; i += 1) {
do_list.push(post(i));
}
for (i = 0; i < 2; i += 1) {
do_list.push(putAttachment(i));
}
return sequence(do_list);
}
prepareDatabase().then(function () {
return jio.get({"_id": "doc1"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "doc1",
"_underscored_meta": "uvalue1",
"meta": "data1",
"_attachments": {
"my_attachment1": {
"length": 8,
"content_type": "text/plain"
}
}
}, "Check document");
return jio.allDocs();
}).then(function (answer) {
answer.data.rows.sort(function (a, b) {
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
});
deepEqual(answer.data, {
"total_rows": 5,
"rows": [
{
"id": "doc0",
"key": "doc0",
"value": {}
},
{
"id": "doc1",
"key": "doc1",
"value": {}
},
{
"id": "doc2",
"key": "doc2",
"value": {}
},
{
"id": "doc3",
"key": "doc3",
"value": {}
},
{
"id": "doc4",
"key": "doc4",
"value": {}
}]
}, "AllDocs with document ids only");
}).fail(unexpectedError).always(start);
});
*/
}));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>JIO S3 Storage Qunit Live Tests</title>
<link rel="stylesheet" href="../../lib/qunit/qunit.css" />
<script src="../../lib/qunit/qunit.js"></script>
<script src="../../lib/rsvp/rsvp-custom.js"></script>
<script src="../../lib/jquery/jquery.min.js"></script>
<script src="../../src/sha256.amd.js"></script>
<script src="../../jio.js"></script>
<script src="../../complex_queries.js"></script>
<script src="../../src/sha1.amd.js"></script>
<script src="../../src/jio.storage/s3storage.js"></script>
<script src="../../src/jio.storage/multisplitstorage.js"></script>
<script src="../jio/util.js"></script>
</head>
<body>
<script>
var s3storage_spec = {};
console.log(location.href);
location.href.split('?')[1].split('&').forEach(function (item) {
s3storage_spec[item.split('=')[0]] = decodeURI(item.split('=').slice(1).join('=')).
replace(/%3A/ig, ':').replace(/%2F/ig, '/');
});
</script>
<h3>JIO initialization</h3>
<form method="get" action="">
<input type="hidden" name="type" value="s3"/>
<input type="text" name="url" placeholder="URL" value="https://jiobucket.s3.amazonaws.com"/>
<input type="text" name="server" placeholder="Bucket" value="jiobucket"/>
<input type="text" name="AWSIdentifier" placeholder="AWSIdentifier" value="AKIAJLNYGVLTV66RHPEQ"/>
<input type="password" name="password" placeholder="Password" value="/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"/>
<input type="submit" value="Run Tests"/>
</form>
<br />
<div id="qunit"></div>
<!--<script src="s3storage.tests.js"></script>-->
<script src="multi.split.s3storage.tests.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>JIO S3 Storage Qunit Live Tests</title>
<link rel="stylesheet" href="../../lib/qunit/qunit.css" />
<script src="../../lib/qunit/qunit.js"></script>
<script src="../../lib/rsvp/rsvp-custom.js"></script>
<script src="../../lib/jquery/jquery.min.js"></script>
<script src="../../src/sha256.amd.js"></script>
<script src="../../jio.js"></script>
<script src="../../complex_queries.js"></script>
<script src="../../src/sha1.amd.js"></script>
<script src="../../src/jio.storage/s3storage.js"></script>
<script src="../../src/jio.storage/splitstorage.js"></script>
<script src="../jio/util.js"></script>
</head>
<body>
<script>
var s3storage_spec = {};
console.log(location.href);
location.href.split('?')[1].split('&').forEach(function (item) {
s3storage_spec[item.split('=')[0]] = decodeURI(item.split('=').slice(1).join('=')).
replace(/%3A/ig, ':').replace(/%2F/ig, '/');
});
</script>
<h3>JIO initialization</h3>
<form method="get" action="">
<input type="hidden" name="type" value="s3"/>
<input type="text" name="url" placeholder="URL" value="https://jiobucket.s3.amazonaws.com"/>
<input type="text" name="server" placeholder="Bucket" value="jiobucket"/>
<input type="text" name="AWSIdentifier" placeholder="AWSIdentifier" value="AKIAJLNYGVLTV66RHPEQ"/>
<input type="password" name="password" placeholder="Password" value="/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"/>
<input type="submit" value="Run Tests"/>
</form>
<br />
<div id="qunit"></div>
<!--<script src="s3storage.tests.js"></script>-->
<script src="split.s3storage.tests.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>JIO S3 Storage Qunit Live Tests</title>
<link rel="stylesheet" href="../../lib/qunit/qunit.css" />
<script src="../../lib/qunit/qunit.js"></script>
<script src="../../lib/rsvp/rsvp-custom.js"></script>
<script src="../../lib/jquery/jquery.min.js"></script>
<script src="../../src/sha256.amd.js"></script>
<script src="../../jio.js"></script>
<script src="../../complex_queries.js"></script>
<script src="../../src/sha1.amd.js"></script>
<script src="../../src/jio.storage/s3storage.js"></script>
<script src="../jio/util.js"></script>
</head>
<body>
<script>
var s3storage_spec = {};
console.log(location.href);
location.href.split('?')[1].split('&').forEach(function (item) {
s3storage_spec[item.split('=')[0]] = decodeURI(item.split('=').slice(1).join('=')).
replace(/%3A/ig, ':').replace(/%2F/ig, '/');
});
</script>
<h3>JIO initialization</h3>
<form method="get" action="">
<input type="hidden" name="type" value="s3"/>
<input type="text" name="url" placeholder="URL" value="https://jiobucket.s3.amazonaws.com"/>
<input type="text" name="server" placeholder="Bucket" value="jiobucket"/>
<input type="text" name="AWSIdentifier" placeholder="AWSIdentifier" value="AKIAJLNYGVLTV66RHPEQ"/>
<input type="password" name="password" placeholder="Password" value="/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"/>
<input type="submit" value="Run Tests"/>
</form>
<br />
<div id="qunit"></div>
<script src="s3storage.tests.js"></script>
</body>
</html>
/*jslint indent: 2, maxlen: 80, nomen: true */ /*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO, jio_tests, window, test, ok, deepEqual, sinon, expect, /*global module, test, stop, start, expect, ok, deepEqual, location, sinon,
module */ davstorage_spec, RSVP, jIO, test_util, dav_storage, btoa, s3storage_spec */
// define([module_name], [dependencies], module); (function () {
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO, jio_tests);
}(['jio', 'jio_tests', 's3storage'], function (jIO, util) {
"use strict"; "use strict";
function generateTools() { var spec, use_fake_server = true;
return { if (typeof s3storage_spec === 'object') {
clock: sinon.useFakeTimers(), use_fake_server = false;
spy: util.ospy, spec = s3storage_spec;
tick: util.otick
};
} }
module("Amazon S3 Storage"); module("S3 Storage");
/* function success(promise) {
Post without id return new RSVP.Promise(function (resolve, reject, notify) {
Create = POST non empty document /*jslint unparam: true*/
Post but document already exists promise.then(resolve, resolve, notify);
*/ }, function () {
promise.cancel();
test("Post", function () {
var o = generateTools(this);
o.jio = jIO.newJio({
"type": "s3",
"AWSIdentifier": "dontcare",
"password": "dontcare",
"server": "jiobucket",
"url": "https://jiobucket.s3.amazonaws.com"
}); });
}
o.server = sinon.fakeServer.create(); test("Scenario", function () {
//Post without ID (ID is generated by storage) var server, responses = [], shared = {}, jio = jIO.createJIO(spec, {
"workspace": {},
o.server.respondWith("GET", "max_retry": 2
"https://jiobucket.s3.amazonaws.com/",
[404, {}, "HTML Response"]
);
o.server.respondWith("POST",
"https://jiobucket.s3.amazonaws.com/",
[204, {}, "HTML Response"]
);
//o.spy(o, "status", 405, "Post without id");
o.spy(o, "jobstatus", "done", "Post without ID");
o.jio.post({}, o.f);
o.clock.tick(1000);
o.server.respond();
o.tick(o);
o.server.restore();
//Post with ID
o.server = sinon.fakeServer.create();
o.server.respondWith("GET",
"https://jiobucket.s3.amazonaws.com/post1",
[404, {}, "HTML Response"]
);
o.server.respondWith("POST",
"https://jiobucket.s3.amazonaws.com/",
[204, {}, "HTML Response"]
);
o.spy(o, "value", {'ok': true, 'id': 'post1'}, "Post with ID");
o.jio.post({"_id": "post1", "title": "myPost1"}, o.f);
o.clock.tick(1000);
o.server.respond();
o.tick(o);
o.server.restore();
//Post but document already exists (update)
o.server = sinon.fakeServer.create();
o.server.respondWith("GET",
"http://s3.amazonaws.com/jiobucket/post2",
[200, {}, "HTML Response"]
);
o.spy(o, "status", 409, "Post but document already exists (update)");
//o.spy(o, "jobstatus", "done", "Post without ID");
o.jio.post({"_id": "post2", "title": "myPost2"}, o.f);
o.clock.tick(1000);
o.server.respond();
o.tick(o);
o.server.restore();
util.closeAndcleanUpJio(o.jio);
}); });
/* stop();
Put without id
Create = PUT non empty document if (use_fake_server) {
Updated the document /*jslint regexp: true */
*/ server = sinon.fakeServer.create();
server.autoRespond = true;
server.autoRespondAfter = 5;
test("Put", function () { server.respondWith(/.*/, function (xhr) {
var o = generateTools(this); var response = responses.shift();
o.jio = jIO.newJio({ if (response) {
"type": "s3", return xhr.respond.apply(xhr, response);
"AWSIdentifier": "dontcare", }
"password": "dontcare", ok(false, "No response associated to the latest request!");
"server": "jiobucket",
"url": "http://s3.amazonaws.com/jiobucket/put1"
}); });
} else {
responses.push = function () {
return;
};
server = {restore: function () {
return;
}};
}
// put without id => id required function postNewDocument() {
o.server = sinon.fakeServer.create(); responses.push([404, {}, '']); // GET
o.spy(o, "status", 20, "Put without id"); responses.push([201, {}, '']); // PUT
o.jio.put({}, o.f); return jio.post({"title": "Unique ID"});
}
o.clock.tick(5000);
o.server.respond();
o.tick(o);
o.server.restore();
//Put non empty document
o.server = sinon.fakeServer.create();
o.server.respondWith(
"GET",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[404, {}, "HTML Response"]
);
o.server.respondWith(
"PUT",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[200, {}, "HTML Response"]
);
o.spy(o, "value", {"ok": true, "id": "http://100%.json"},
"PUT non empty document");
o.jio.put({"_id": "http://100%.json", "title": "myPut1"}, o.f);
o.clock.tick(5000);
o.server.respond();
o.tick(o);
o.server.restore();
//Put an existing document (update)
o.server = sinon.fakeServer.create();
o.server.respondWith(
"GET",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[200, {}, "HTML Response"]
);
o.server.respondWith(
"PUT",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[200, {}, "HTML Response"]
);
o.spy(o, "value", {"ok": true, "id": "http://100%.json"},
"PUT non empty document");
o.jio.put({"_id": "http://100%.json", "title": "myPut1"}, o.f);
o.clock.tick(1000);
o.server.respond();
o.tick(o);
o.server.restore();
util.closeAndcleanUpJio(o.jio);
}); function postNewDocumentTest(answer) {
var uuid = answer.id;
answer.id = "<uuid>";
deepEqual(answer, {
"id": "<uuid>",
"method": "post",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Post a new document");
ok(/^no_document_id_[0-9]+$/.test(uuid), "New document id should look like " +
"no_document_id_479658600408584 : " + uuid);
shared.created_document_id = uuid;
}
test("PutAttachment", function () { function getCreatedDocument() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": shared.created_document_id,
"title": "Unique ID"
})]); // GET
return jio.get({"_id": shared.created_document_id});
}
var o = generateTools(this); function getCreatedDocumentTest(answer) {
deepEqual(answer, {
"data": {
"_id": shared.created_document_id,
"title": "Unique ID"
},
"id": shared.created_document_id,
"method": "get",
"result": "success",
"status": 200,
"statusText": "Ok"
}, "Get new document");
}
o.jio = jIO.newJio({ function postSpecificDocument() {
"type": "s3", responses.push([404, {}, '']); // GET
"AWSIdentifier": "dontcare", responses.push([201, {}, '']); // PUT
"password": "dontcare", return jio.post({"_id": "b", "title": "Bee"});
"server": "jiobucket", }
"url": "https://jiobucket.s3.amazonaws.com"
});
//PutAttachment without document ID (document ID is required) function postSpecificDocumentTest(answer) {
o.server = sinon.fakeServer.create(); deepEqual(answer, {
"id": "b",
//PutAttachment without attachment ID (attachment ID is required) "method": "post",
o.spy(o, "status", 20, "PutAttachment without doc id -> 20"); "result": "success",
o.jio.putAttachment({"_attachment": "putattmt1"}, o.f); "status": 204,
o.tick(o); "statusText": "No Content"
}, "Post specific document");
// putAttachment without attachment id => 22 Attachment Id Required }
o.spy(o, "status", 22, "PutAttachment without attachment id -> 22");
o.jio.putAttachment({"_id": "http://100%.json"}, o.f); function listDocuments() {
o.tick(o); //quelle utilité à pousser le xml ?
responses.push([
//PutAttachment without underlying document (document is required)
o.server = sinon.fakeServer.create();
o.server.respondWith(
"GET",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[404, {}, "HTML Response"]
);
o.spy(o, "status", 404, "PutAttachment without document -> 404");
o.jio.putAttachment({
"_id": "http://100%.json",
"_attachment": "putattmt2"
}, {"max_retry": 1}, o.f);
o.clock.tick(1000);
o.server.respond();
o.tick(o);
o.server.restore();
//PutAttachment
o.server = sinon.fakeServer.create();
o.server.respondWith(
"GET",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[
200, 200,
{"Content-Type": "text/plain"}, {"Content-Type": "text/xml"},''
'{"_id":"http://100%.json","title":"Hi There!"}' ]); // PROPFIND
] return jio.allDocs();
); }
o.server.respondWith(
"PUT",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[200, {}, "HTML Response"]
);
o.server.respondWith(
"PUT",
"http://s3.amazonaws.com/jiobucket" +
"/http:%252F%252F100%2525_.json.body_.html",
[200, {}, "HTML Response"]
);
o.spy(o, "value", {
"ok": true,
"id": "http://100%.json",
"attachment": "body.html"
}, "PutAttachment");
o.jio.putAttachment({
"_id": "http://100%.json",
"_attachment": "body.html",
"_mimetype": "text/html",
"_data": "<h1>Hi There!!</h1><p>How are you?</p>"
}, {"max_retry": 1}, o.f);
o.clock.tick(1000);
o.server.respond();
o.tick(o);
o.server.restore();
util.closeAndcleanUpJio(o.jio);
function list2DocumentsTest(answer) {
if (answer && answer.data && Array.isArray(answer.data.rows)) {
answer.data.rows.sort(function (a) {
return a.id === "b" ? 1 : 0;
}); });
}
deepEqual(answer, {
"data": {
"total_rows": 2,
"rows": [{
"id": shared.created_document_id,
"value": {}
}, {
"id": "b",
"value": {}
}]
},
"method": "allDocs",
"result": "success",
"status": 200,
"statusText": "Ok"
}, "List 2 documents");
}
function removeCreatedDocument() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": shared.created_document_id,
"title": "Unique ID"
})]); // GET
responses.push([204, {}, '']); // DELETE
return jio.remove({"_id": shared.created_document_id});
}
/* function removeCreatedDocumentTest(answer) {
Get non existing document deepEqual(answer, {
Get non existing attachment "id": shared.created_document_id,
Get document "method": "remove",
Get non existing attachment (doc exists) "result": "success",
Get attachment "status": 204,
*/ "statusText": "No Content"
}, "Remove first document.");
test("Get", function () { }
var o = generateTools(this);
o.jio = jIO.newJio({
"type": "s3",
"AWSIdentifier": "dontcare",
"password": "dontcare",
"server": "jiobucket",
"url": "https://jiobucket.s3.amazonaws.com"
});
//Get non existing document function removeSpecificDocument() {
o.server = sinon.fakeServer.create(); responses.push([200, {
o.server.respondWith("GET", "Content-Type": "application/octet-stream"
"https://jiobucket.s3.amazonaws.com/doc", }, JSON.stringify({
[404, {}, "HTML Response"] "_id": "b",
); "title": "Bee"
})]); // GET
responses.push([204, {}, '']); // DELETE
return jio.remove({"_id": "b"});
}
o.spy(o, "status", 404, "Get non existing document"); function removeSpecificDocumentTest(answer) {
deepEqual(answer, {
"id": "b",
"method": "remove",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove second document.");
}
function listEmptyStorage() {
responses.push([
200,
{"Content-Type": "text/xml"},
''
]); // PROPFIND
return jio.allDocs();
}
o.jio.get("doc", {"max_retry": 1}, o.f); function listEmptyStorageTest(answer) {
deepEqual(answer, {
"data": {
"total_rows": 0,
"rows": []
},
"method": "allDocs",
"result": "success",
"status": 200,
"statusText": "Ok"
}, "List empty storage");
}
o.clock.tick(5000); function putNewDocument() {
o.server.respond(); responses.push([404, {}, '']); // GET
o.tick(o); responses.push([200, {}, '']); // PUT
o.server.restore(); return jio.put({"_id": "a", "title": "Hey"});
}
//Get document function putNewDocumentTest(answer) {
o.server = sinon.fakeServer.create(); deepEqual(answer, {
o.server.respondWith( "id": "a",
"GET", "method": "put",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json", "result": "success",
[ "status": 200,
200, "statusText": "Ok"
{"Content-Type": "text/plain"}, }, "Put new document");
'{"_id":"http://100%.json","title":"Hi There!"}' }
]
);
function getCreatedDocument2() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": "a",
"title": "Hey"
})]); // GET
return jio.get({"_id": "a"});
}
o.spy(o, "value", {"_id": "http://100%.json", "title": "Hi There!"}, function getCreatedDocument2Test(answer) {
"Get document"); deepEqual(answer, {
o.jio.get({"_id": "http://100%.json"}, {"max_retry": 1}, o.f); "data": {
"_id": "a",
"title": "Hey"
},
"id": "a",
"method": "get",
"result": "success",
"status": 200,
"statusText": "Ok"
}, "Get new document");
}
o.clock.tick(5000); function postSameDocument() {
o.server.respond(); responses.push([200, {
o.tick(o); "Content-Type": "application/octet-stream"
o.server.restore(); }, JSON.stringify({
"_id": "a",
"title": "Hey"
})]); // GET
return success(jio.post({"_id": "a", "title": "Hoo"}));
}
util.closeAndcleanUpJio(o.jio); function postSameDocumentTest(answer) {
}); deepEqual(answer, {
"error": "conflict",
"id": "a",
"message": "Cannot create document",
"method": "post",
"reason": "Document already exists",
"result": "error",
"status": 409,
"statusText": "Conflict"
}, "Unable to post the same document (conflict)");
}
test("GetAttachment", function () { function createAttachment() {
var o = generateTools(this); responses.push([200, {
o.jio = jIO.newJio({ "Content-Type": "application/octet-stream"
"type": "s3", }, JSON.stringify({
"AWSIdentifier": "dontcare", "_id": "a",
"password": "dontcare", "title": "Hey"
"server": "jiobucket", })]); // GET
"url": "https://jiobucket.s3.amazonaws.com" responses.push([201, {}, '']); // PUT (attachment)
responses.push([204, {}, '']); // PUT (metadata)
return jio.putAttachment({
"_id": "a",
"_attachment": "aa",
"_data": "aaa",
"_content_type": "text/plain"
}); });
}
function createAttachmentTest(answer) {
deepEqual(answer, {
"attachment": "aa",
"digest":"sha256-9834876dcfb05cb167a5c24953eba58c4"+
"ac89b1adf57f28f2f9d09af107ee8f0",
"id": "a",
"method": "putAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Create new attachment");
}
//Get non existing attachment function updateAttachment() {
o.server = sinon.fakeServer.create(); responses.push([200, {
o.server.respondWith( "Content-Type": "application/octet-stream"
"GET", }, JSON.stringify({
"http://s3.amazonaws.com/jiobucket" + "_id": "a",
"/http:%252F%252F100%2525_.json.body_.html", "title": "Hey",
[404, {}, "HTML Response"] "_attachments": {
); "aa": {
"content_type": "text/plain",
o.spy(o, "status", 404, "Get non existing attachment"); "digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"0728e095ff24218119d51bd22475363",
o.jio.getAttachment({ "length": 3
"_id": "http://100%.json", }
"_attachment": "body.html" }
}, {"max_retry": 1}, o.f); })]); // GET
responses.push([204, {}, '']); // PUT (attachment)
o.clock.tick(5000); responses.push([204, {}, '']); // PUT (metadata)
o.server.respond(); return jio.putAttachment({
o.tick(o); "_id": "a",
o.server.restore(); "_attachment": "aa",
"_data": "aab",
//Get attachment "_content_type": "text/plain"
o.server = sinon.fakeServer.create();
o.server.respondWith(
"GET",
"http://s3.amazonaws.com/jiobucket" +
"/http:%252F%252F100%2525_.json.body_.html",
[200, {"Content-Type": "text/plain"}, "My Attachment Content"]
);
o.spy(o, "value", "My Attachment Content", "Get attachment");
o.jio.getAttachment({
"_id": "http://100%.json",
"_attachment": "body.html"
}, {"max_retry": 1}, o.f);
o.clock.tick(5000);
o.server.respond();
o.tick(o);
o.server.restore();
util.closeAndcleanUpJio(o.jio);
}); });
}
function updateAttachmentTest(answer) {
deepEqual(answer, {
"attachment": "aa",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"0728e095ff24218119d51bd22475363",
"id": "a",
"method": "putAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Update last attachment");
}
//begins the remove tests function createAnotherAttachment() {
responses.push([200, {
/* "Content-Type": "application/octet-stream"
Remove inexistent document }, JSON.stringify({
Remove inexistent document/attachment "_id": "a",
Remove document "title": "Hey",
Check index file "_attachments": {
Check if document has been removed "aa": {
Remove one of multiple attachment "content_type": "text/plain",
Check index file "digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
Remove one document and attachment together "0728e095ff24218119d51bd22475363",
Check index file "length": 3
Check if attachment has been removed }
Check if document has been removed }
*/ })]); // GET
responses.push([201, {}, '']); // PUT (attachment)
test("Remove", function () { responses.push([204, {}, '']); // PUT (metadata)
return jio.putAttachment({
var o = generateTools(this); "_id": "a",
"_attachment": "ab",
o.jio = jIO.newJio({ "_data": "aba",
"type": "s3", "_content_type": "text/plain"
"AWSIdentifier": "dontcare",
"password": "dontcare",
"server": "jiobucket",
"url": "https://jiobucket.s3.amazonaws.com/"
}); });
}
//Remove non-existing document function createAnotherAttachmentTest(answer) {
o.server = sinon.fakeServer.create(); deepEqual(answer, {
o.server.respondWith( "attachment": "ab",
"DELETE", "digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json", "ed343e6c739e54131fcb3a56e4bc1bd",
[404, {}, "HTML RESPONSE"] "id": "a",
); "method": "putAttachment",
"result": "success",
o.spy(o, "status", 404, "Remove non existing document"); "status": 204,
o.jio.remove({"_id": "http://100%.json"}, o.f); "statusText": "No Content"
o.clock.tick(5000); }, "Create another attachment");
o.server.respond(); }
o.server.restore();
function updateLastDocument() {
//Remove document responses.push([200, {
o.server = sinon.fakeServer.create(); "Content-Type": "application/octet-stream"
o.server.respondWith( }, JSON.stringify({
"DELETE", "_id": "a",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json", "title": "Hey",
[200, {"Content-Type": "text/plain"}, "My Attachment Content"]
);
o.spy(o, "value", {"ok": true, "id": "http://100%.json"},
"Remove document");
o.jio.remove({"_id": "http://100%.json"}, o.f);
o.clock.tick(5000);
o.server.respond();
o.tick(o);
o.server.restore();
//Remove document with multiple attachments
o.server = sinon.fakeServer.create();
o.server.respondWith(
"GET",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[
200,
{"Content-Type": "text/html"},
JSON.stringify({
"_attachments": { "_attachments": {
"body.html": { "aa": {
"length": 32, "content_type": "text/plain",
"digest": "md5-dontcare", "digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"content_type": "text/html" "0728e095ff24218119d51bd22475363",
"length": 3
}, },
"other": { "ab": {
"length": 3, "content_type": "text/plain",
"digest": "md5-dontcare-again", "digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
"content_type": "text/plain" "ed343e6c739e54131fcb3a56e4bc1bd",
} "length": 3
} }
}) }
] })]); // GET
); responses.push([204, {}, '']); // PUT
return jio.put({"_id": "a", "title": "Hoo"});
o.server.respondWith( }
"DELETE",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json",
[200, {"Content-Type": "text/plain"}, "<h1>Deleted</h1>"]
);
o.server.respondWith(
"DELETE",
"http://s3.amazonaws.com/jiobucket" +
"/http:%252F%252F100%2525_.json.body_.html",
[200, {"Content-Type": "text/plain"}, "<h1>Deleted</h1>"]
);
o.server.respondWith(
"DELETE",
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json.other",
[200, {"Content-Type": "text/plain"}, "<h1>Deleted</h1>"]
);
o.spy(o, "value", {"ok": true, "id": "http://100%.json"},
"Remove document containing multiple attachments");
o.jio.remove({"_id": "http://100%.json"}, {"max_retry": 1}, o.f);
o.clock.tick(1000);
o.server.respond();
o.tick(o);
o.server.restore();
util.closeAndcleanUpJio(o.jio);
});
test("RemoveAttachment", function () { function updateLastDocumentTest(answer) {
deepEqual(answer, {
"id": "a",
"method": "put",
"result": "success",
"status": 200,
"statusText": "Ok"
}, "Update document metadata");
}
var o = generateTools(this); function getFirstAttachment() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": "a",
"title": "Hoo",
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"0728e095ff24218119d51bd22475363",
"length": 3
},
"ab": {
"content_type": "text/plain",
"digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
"ed343e6c739e54131fcb3a56e4bc1bd",
"length": 3
}
}
})]); // GET
responses.push([200, {
"Content-Type": "application/octet-stream"
}, "aab"]); // GET
return jio.getAttachment({"_id": "a", "_attachment": "aa"});
}
o.jio = jIO.newJio({ function getFirstAttachmentTest(answer) {
"type": "s3", var blob = answer.data;
"AWSIdentifier": "dontcare", answer.data = "<blob>";
"password": "dontcare", deepEqual(answer, {
"server": "jiobucket", "attachment": "aa",
"url": "https://jiobucket.s3.amazonaws.com/" "data": "<blob>",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"0728e095ff24218119d51bd22475363",
"id": "a",
"method": "getAttachment",
"result": "success",
"status": 200,
"statusText": "Ok"
}, "Get first attachment");
return jIO.util.readBlobAsText(blob).then(function (e) {
deepEqual(blob.type, "text/plain", "Check blob type");
deepEqual(e.target.result, "aab", "Check blob text content");
}, function (err) {
deepEqual(err, "no error", "Check blob text content");
}); });
}
//Remove non-existing attachment function getSecondAttachment() {
o.server = sinon.fakeServer.create(); responses.push([200, {
"Content-Type": "application/octet-stream"
o.server.respondWith( }, JSON.stringify({
"DELETE", "_id": "a",
"http://s3.amazonaws.com/jiobucket" + "title": "Hoo",
"/http:%252F%252F100%2525_.json.body_.html", "_attachments": {
[404, {}, "HTML RESPONSE"] "aa": {
); "content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
o.spy(o, "status", 404, "Remove non existing attachment"); "0728e095ff24218119d51bd22475363",
o.jio.removeAttachment({ "length": 3
"_id": "http://100%.json", },
"_attachment": "body.html" "ab": {
}, {"max_retry": 1}, o.f); "content_type": "text/plain",
o.clock.tick(5000); "digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
o.server.respond(); "ed343e6c739e54131fcb3a56e4bc1bd",
o.server.restore(); "length": 3
}
//Remove attachment }
o.server = sinon.fakeServer.create(); })]); // GET
responses.push([200, {
o.server.respondWith( "Content-Type": "application/octet-stream"
"GET", }, "aba"]); // GET
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json", return jio.getAttachment({"_id": "a", "_attachment": "ab"});
[ }
200,
{"Content-Type": "text/plain"}, function getSecondAttachmentTest(answer) {
'{"_id":"http://100%.json","title":"Hi There!"}' var blob = answer.data;
] answer.data = "<blob>";
); deepEqual(answer, {
"attachment": "ab",
o.server.respondWith( "data": "<blob>",
"PUT", "digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
"http://s3.amazonaws.com/jiobucket/http:%252F%252F100%2525_.json", "ed343e6c739e54131fcb3a56e4bc1bd",
[ "id": "a",
200, "method": "getAttachment",
{"Content-Type": "text/plain"}, "result": "success",
'{"_id":"http://100%.json","title":"Hi There!"}' "status": 200,
] "statusText": "Ok"
); }, "Get first attachment");
return jIO.util.readBlobAsText(blob).then(function (e) {
o.server.respondWith( deepEqual(blob.type, "text/plain", "Check blob type");
"DELETE", deepEqual(e.target.result, "aba", "Check blob text content");
"http://s3.amazonaws.com/jiobucket" + }, function (err) {
"/http:%252F%252F100%2525_.json.body_.html", deepEqual(err, "no error", "Check blob text content");
[200, {"Content-Type": "text/plain"}, "My Attachment Content"]
);
o.spy(o, "value", {
"ok": true,
"id": "http://100%.json",
"attachment": "body.html"
}, "Remove attachment");
o.jio.removeAttachment({
"_id": "http://100%.json",
"_attachment": "body.html"
}, {"max_retry": 1}, o.f);
o.clock.tick(5000);
o.server.respond();
o.tick(o);
o.server.restore();
util.closeAndcleanUpJio(o.jio);
}); });
}
function getLastDocument() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": "a",
"title": "Hoo",
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"0728e095ff24218119d51bd22475363",
"length": 3
},
"ab": {
"content_type": "text/plain",
"digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
"ed343e6c739e54131fcb3a56e4bc1bd",
"length": 3
}
}
})]); // GET
return jio.get({"_id": "a"});
}
test("AllDocs", function () { function getLastDocumentTest(answer) {
deepEqual(answer, {
"data": {
"_id": "a",
"title": "Hoo",
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"0728e095ff24218119d51bd22475363",
"length": 3
},
"ab": {
"content_type": "text/plain",
"digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
"ed343e6c739e54131fcb3a56e4bc1bd",
"length": 3
}
}
},
"id": "a",
"method": "get",
"result": "success",
"status": 200,
"statusText": "Ok"
}, "Get last document metadata");
}
var o = generateTools(this); function removeSecondAttachment() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": "a",
"title": "Hoo",
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"0728e095ff24218119d51bd22475363",
"length": 3
},
"ab": {
"content_type": "text/plain",
"digest": "sha256-e124adcce1fb2f88e1ea799c3d0820845" +
"ed343e6c739e54131fcb3a56e4bc1bd",
"length": 3
}
}
})]); // GET
responses.push([204, {}, '']); // PUT
responses.push([204, {}, '']); // DELETE
return jio.removeAttachment({"_id": "a", "_attachment": "ab"});
}
o.jio = jIO.newJio({ function removeSecondAttachmentTest(answer) {
"type": "s3", deepEqual(answer, {
"AWSIdentifier": "dontcare", "attachment": "ab",
"password": "dontcare", "id": "a",
"server": "jiobucket", "method": "removeAttachment",
"url": "https://jiobucket.s3.amazonaws.com/" "result": "success",
}); "status": 204,
"statusText": "No Content"
}, "Remove second document");
}
//allDocs without option function getInexistentSecondAttachment() {
o.server = sinon.fakeServer.create(); responses.push([200, {
"Content-Type": "application/octet-stream"
o.server.respondWith( }, JSON.stringify({
"GET", "_id": "a",
"http://s3.amazonaws.com/jiobucket/", "title": "Hoo",
[
204,
{},
'<?xml version="1.0" encoding="UTF-8"?><ListBucketResult xml' +
'ns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>jiobucke' +
't</Name><Prefix></Prefix><Marker></Marker><MaxKeys>1000</Ma' +
'xKeys><IsTruncated>false</IsTruncated><Contents><Key>docume' +
'ntONE</Key><LastModified>2013-05-03T15:32:01.000Z</LastModi' +
'fied><ETag>&quot;8a65389818768e1f5e6530a949233581&quot;</ET' +
'ag><Size>163</Size><Owner><ID>5d09e586ab92acad85e9d053f769c' +
'ce65f82178e218d9ac9b0473f3ce7f89606</ID><DisplayName>jonath' +
'an.rivalan</DisplayName></Owner><StorageClass>STANDARD</Sto' +
'rageClass></Contents><Contents><Key>documentONE.1st_Attachm' +
'ent_manual</Key><LastModified>2013-05-03T15:32:02.000Z</Las' +
'tModified><ETag>&quot;f391dec65366d2b470406bc7b9595dea&quot' +
';</ETag><Size>35</Size><Owner><ID>5d09e586ab92acad85e9d053f' +
'769cce65f82178e218d9ac9b0473f3ce7f89606</ID><DisplayName>jo' +
'nathan.rivalan</DisplayName></Owner><StorageClass>STANDARD<' +
'/StorageClass></Contents></ListBucketResult>'
]
);
o.spy(o, "jobstatus", "done", "AllDocs without include docs");
o.jio.allDocs(o.f);
o.clock.tick(5000);
o.server.respond();
o.tick(o);
o.server.restore();
//allDocs with the include docs option
o.server = sinon.fakeServer.create();
o.server.respondWith(
"GET",
"http://s3.amazonaws.com/jiobucket/",
[
204,
{},
'<?xml version="1.0" encoding="UTF-8"?><ListBucketResult xml' +
'ns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>jiobucke' +
't</Name><Prefix></Prefix><Marker></Marker><MaxKeys>1000</Ma' +
'xKeys><IsTruncated>false</IsTruncated><Contents><Key>docume' +
'ntONE</Key><LastModified>2013-05-03T15:32:01.000Z</LastModi' +
'fied><ETag>&quot;8a65389818768e1f5e6530a949233581&quot;</ET' +
'ag><Size>163</Size><Owner><ID>5d09e586ab92acad85e9d053f769c' +
'ce65f82178e218d9ac9b0473f3ce7f89606</ID><DisplayName>jonath' +
'an.rivalan</DisplayName></Owner><StorageClass>STANDARD</Sto' +
'rageClass></Contents><Contents><Key>documentONE.1st_Attachm' +
'ent_manual</Key><LastModified>2013-05-03T15:32:02.000Z</Las' +
'tModified><ETag>&quot;f391dec65366d2b470406bc7b9595dea&quot' +
';</ETag><Size>35</Size><Owner><ID>5d09e586ab92acad85e9d053f' +
'769cce65f82178e218d9ac9b0473f3ce7f89606</ID><DisplayName>jo' +
'nathan.rivalan</DisplayName></Owner><StorageClass>STANDARD<' +
'/StorageClass></Contents></ListBucketResult>'
]
);
o.server.respondWith(
"GET",
"http://jiobucket.s3.amazonaws.com/documentONE",
[
200,
{"Content-Type": "text/html"},
JSON.stringify({
"_attachments": { "_attachments": {
"body.html": { "aa": {
"length": 32, "content_type": "text/plain",
"digest": "md5-dontcare", "digest": "sha256-38760eabb666e8e61ee628a17c4090cc5"+
"content_type": "text/html" "0728e095ff24218119d51bd22475363",
"length": 3
}
}
})]); // GET
return success(jio.getAttachment({"_id": "a", "_attachment": "ab"}));
}
function getInexistentSecondAttachmentTest(answer) {
deepEqual(answer, {
"attachment": "ab",
"error": "not_found",
"id": "a",
"message": "File does not exist",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get inexistent second attachment");
}
function getOneAttachmentDocument() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": "a",
"title": "Hoo",
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5" +
"0728e095ff24218119d51bd22475363",
"length": 3
}
}
})]); // GET
return jio.get({"_id": "a"});
}
function getOneAttachmentDocumentTest(answer) {
deepEqual(answer, {
"data": {
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5" +
"0728e095ff24218119d51bd22475363",
"length": 3
}
},
"_id": "a",
"title": "Hoo"
}, },
"other": { "id": "a",
"length": 3, "method": "get",
"digest": "md5-dontcare-again", "result": "success",
"content_type": "text/plain" "status": 200,
"statusText": "Ok"
}, "Get document metadata");
}
function removeSecondAttachmentAgain() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": "a",
"title": "Hoo",
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5" +
"0728e095ff24218119d51bd22475363",
"length": 3
}
}
})]); // GET
return success(jio.removeAttachment({"_id": "a", "_attachment": "ab"}));
}
function removeSecondAttachmentAgainTest(answer) {
deepEqual(answer, {
"attachment": "ab",
"error": "not_found",
"id": "a",
"message": "This Attachment does not exist",
"method": "removeAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove inexistent attachment");
}
function removeDocument() {
responses.push([200, {
"Content-Type": "application/octet-stream"
}, JSON.stringify({
"_id": "a",
"title": "Hoo",
"_attachments": {
"aa": {
"content_type": "text/plain",
"digest": "sha256-38760eabb666e8e61ee628a17c4090cc5" +
"0728e095ff24218119d51bd22475363",
"length": 3
}
}
})]); // GET
responses.push([204, {}, '']); // DELETE (metadata)
responses.push([204, {}, '']); // DELETE (attachment aa)
return jio.remove({"_id": "a"});
} }
function removeDocumentTest(answer) {
deepEqual(answer, {
"id": "a",
"method": "remove",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove document and its attachments");
} }
})
]
);
function getInexistentFirstAttachment() {
responses.push([404, {}, '']); // GET
return success(jio.getAttachment({"_id": "a", "_attachment": "aa"}));
}
o.spy(o, "jobstatus", "done", "AllDocs with include docs"); function getInexistentFirstAttachmentTest(answer) {
o.jio.allDocs({"include_docs": true}, o.f); deepEqual(answer, {
o.clock.tick(5000); "attachment": "aa",
o.server.respond(); "error": "not_found",
o.tick(o); "id": "a",
o.server.restore(); "message": "File does not exist",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get inexistent first attachment");
}
function getInexistentDocument() {
responses.push([404, {}, '']); // GET
return success(jio.get({"_id": "a"}));
}
function getInexistentDocumentTest(answer) {
deepEqual(answer, {
"error": "not_found",
"id": "a",
"message": "File does not exist",
"method": "get",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get inexistent document");
}
function removeInexistentDocument() {
responses.push([404, {}, '']); // GET
return success(jio.remove({"_id": "a"}));
}
function removeInexistentDocumentTest(answer) {
deepEqual(answer, {
"error": "not_found",
"id": "a",
"message": "File does not exist",
"method": "remove",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove already removed document");
}
function unexpectedError(error) {
if (error instanceof Error) {
deepEqual([
error.name + ": " + error.message,
error
], "UNEXPECTED ERROR", "Unexpected error");
} else {
deepEqual(error, "UNEXPECTED ERROR", "Unexpected error");
}
}
// # Post new documents, list them and remove them
// post a 201
postNewDocument().then(postNewDocumentTest).
// get 200
then(getCreatedDocument).then(getCreatedDocumentTest).
// post b 201
then(postSpecificDocument).then(postSpecificDocumentTest).
//postSpecificDocument().then(postSpecificDocumentTest).
// allD 200 2 documents
then(listDocuments).then(list2DocumentsTest).
//listDocuments().then(list2DocumentsTest).
// remove a 204
then(removeCreatedDocument).then(removeCreatedDocumentTest).
// remove b 204
then(removeSpecificDocument).then(removeSpecificDocumentTest).
// allD 200 empty storage
then(listEmptyStorage).then(listEmptyStorageTest).
// # Create and update documents, and some attachment and remove them
// put 201
then(putNewDocument).then(putNewDocumentTest).
// get 200
then(getCreatedDocument2).then(getCreatedDocument2Test).
// post 409
then(postSameDocument).then(postSameDocumentTest).
// putA a 204
then(createAttachment).then(createAttachmentTest).
// putA a 204
then(updateAttachment).then(updateAttachmentTest).
// putA b 204
then(createAnotherAttachment).then(createAnotherAttachmentTest).
// put 204
then(updateLastDocument).then(updateLastDocumentTest).
// getA a 200
then(getFirstAttachment).then(getFirstAttachmentTest).
// getA b 200
then(getSecondAttachment).then(getSecondAttachmentTest).
// get 200
then(getLastDocument).then(getLastDocumentTest).
// removeA b 204
then(removeSecondAttachment).then(removeSecondAttachmentTest).
// getA b 404
then(getInexistentSecondAttachment).
then(getInexistentSecondAttachmentTest).
// get 200
then(getOneAttachmentDocument).then(getOneAttachmentDocumentTest).
// removeA b 404
then(removeSecondAttachmentAgain).then(removeSecondAttachmentAgainTest).
// remove 204
then(removeDocument).then(removeDocumentTest).
// getA a 404
then(getInexistentFirstAttachment).then(getInexistentFirstAttachmentTest).
// get 404
then(getInexistentDocument).then(getInexistentDocumentTest).
// remove 404
then(removeInexistentDocument).then(removeInexistentDocumentTest).
// check 204
//then(checkDocument).done(checkDocumentTest).
//then(checkStorage).done(checkStorageTest).
fail(unexpectedError).
always(start).
always(server.restore.bind(server));
util.closeAndcleanUpJio(o.jio);
}); });
})); module("SplitStorage + S3 Storage");
}());
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO, test_util, RSVP, test, ok, deepEqual, module, stop,
start, hex_sha256 */
// define([module_name], [dependencies], module);
(function (dependencies, module) {
"use strict";
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO, test_util, RSVP);
}([
'jio',
'test_util',
'rsvp',
's3storage',
'splitstorage'
], function (jIO, util, RSVP) {
"use strict";
var tool = {
"readBlobAsBinaryString": jIO.util.readBlobAsBinaryString
};
function reverse(promise) {
return new RSVP.Promise(function (resolve, reject, notify) {
promise.then(reject, resolve, notify);
}, function () {
promise.cancel();
});
}
/**
* sequence(thens): Promise
*
* Executes a sequence of *then* callbacks. It acts like
* `smth().then(callback).then(callback)...`. The first callback is called
* with no parameter.
*
* Elements of `thens` array can be a function or an array contaning at most
* three *then* callbacks: *onFulfilled*, *onRejected*, *onNotified*.
*
* When `cancel()` is executed, each then promises are cancelled at the same
* time.
*
* @param {Array} thens An array of *then* callbacks
* @return {Promise} A new promise
*/
function sequence(thens) {
var promises = [];
return new RSVP.Promise(function (resolve, reject, notify) {
var i;
promises[0] = new RSVP.Promise(function (resolve) {
resolve();
});
for (i = 0; i < thens.length; i += 1) {
if (Array.isArray(thens[i])) {
promises[i + 1] = promises[i].
then(thens[i][0], thens[i][1], thens[i][2]);
} else {
promises[i + 1] = promises[i].then(thens[i]);
}
}
promises[i].then(resolve, reject, notify);
}, function () {
var i;
for (i = 0; i < promises.length; i += 1) {
promises[i].cancel();
}
});
}
function unexpectedError(error) {
if (error instanceof Error) {
deepEqual([
error.name + ": " + error.message,
error
], "UNEXPECTED ERROR", "Unexpected error");
} else {
deepEqual(error, "UNEXPECTED ERROR", "Unexpected error");
}
}
module("SplitStorage + S3 Storage");
test("Post", function () {
var shared = {}, jio, jio_s3_list = [];
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
jio_s3_list[0] = jIO.createJIO(shared.s3_storage_description1, {
"workspace": shared.workspace
});
jio_s3_list[1] = jIO.createJIO(shared.s3_storage_description2, {
"workspace": shared.workspace
});
jio_s3_list.run = function (method, argument) {
var i, promises = [];
for (i = 0; i < this.length; i += 1) {
promises[i] = this[i][method].apply(this[i], argument);
}
return RSVP.all(promises);
};
jio_s3_list.get = function () {
return this.run("get", arguments);
};
stop();
// post without id
jio.post({
"_underscored_meta": "uvalue",
"meta": "data"
})
.then(function (answer) {
shared.uuid = answer.id;
answer.id = "<uuid>";
ok(util.isUuid(shared.uuid), "Uuid should look like " +
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx : " + shared.uuid);
deepEqual(answer, {
"id": "<uuid>",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document without id");
// check uploaded documents
return jio_s3_list.get({"_id": shared.uuid});
})
.then(function (answers) {
var i;
for (i = 0; i < answers.length; i += 1) {
deepEqual(answers[i].data, {
"_id": shared.uuid,
"_underscored_meta": "uvalue",
"data": i === 0 ? "{\"meta\"" : ":\"data\"}"
}, "Check uploaded document in sub storage " + (i + 1));
}
// post with id
return jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
});
})
.then(function (answer) {
deepEqual(answer, {
"id": "one",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post document with id");
// check uploaded documents
return jio_s3_list.get({"_id": "one"});
})
.then(function (answers) {
deepEqual(answers[0].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "{\"meta\":\"data\","
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_id": "one",
"_underscored_meta": "uvalue",
"data": "\"hello\":\"world\"}"
}, "Check uploaded document in sub storage 2");
// post with id
return reverse(jio.post({
"_id": "one",
"_underscored_meta": "uvalue",
"meta": "data",
"hello": "world"
}));
})
.then(function (answer) {
deepEqual(answer, {
"error": "conflict",
"id": "one",
"message": "Unable to post document",
"method": "post",
"reason": "Document already exists",
"result": "error",
"status": 409,
"statusText": "Conflict"
}, "Post document with same id -> 409 Conflict");
})
.fail(unexpectedError).always(start);
});
test("PutAttachment", function () {
var shared = {}, jio, jio_s3_list = [];
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "putAttachment1",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "putAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
jio_s3_list[0] = jIO.createJIO(shared.s3_storage_description1, {
"workspace": shared.workspace
});
jio_s3_list[1] = jIO.createJIO(shared.s3_storage_description2, {
"workspace": shared.workspace
});
jio_s3_list.run = function (method, argument) {
var i, promises = [];
for (i = 0; i < this.length; i += 1) {
promises[i] = this[i][method].apply(this[i], argument);
}
return RSVP.all(promises);
};
jio_s3_list.get = function () {
return this.run("get", arguments);
};
jio_s3_list.getAttachmentAsBinaryString = function () {
return this.run("getAttachment", arguments).then(function (answers) {
var i, promises = [];
for (i = 0; i < answers.length; i += 1) {
promises[i] = tool.readBlobAsBinaryString(answers[i].data);
}
return RSVP.all(promises);
});
};
stop();
return reverse(jio.putAttachment({
"_id": "two",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "two",
"message": "Unable to put attachment",
"method": "putAttachment",
"reason": "Document does not exist",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Put attachment on a inexistent document -> 404 Not Found");
return jio.post({
"_id": "two",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "two",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "two",
"method": "putAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put attachment on a document");
// check uploaded documents
return jio_s3_list.get({"_id": "two"});
}).then(function (answers) {
deepEqual(answers[0].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-ebf2d770a6a2dfa135f6c81431f22fc3cbcde9ae" +
"e52759ca9e520d4d964c1322", // sha256("My ")
"length": 3
}
},
"_id": "two",
"_underscored_meta": "uvalue",
"data": "{\"meta\""
}, "Check uploaded document in sub storage 1");
deepEqual(answers[1].data, {
"_attachments": {
"my_attachment": {
"content_type": "text/plain",
"digest": "sha256-cec3a9b89b2e391393d0f68e4bc12a9fa6cf358b" +
"3cdf79496dc442d52b8dd528", // sha256("Data")
"length": 4
}
},
"_id": "two",
"_underscored_meta": "uvalue",
"data": ":\"data\"}"
}, "Check uploaded document in sub storage 2");
return jio_s3_list.getAttachmentAsBinaryString({
"_id": "two",
"_attachment": "my_attachment"
});
}).then(function (events) {
deepEqual(events[0].target.result, "My ",
"Check uploaded document in sub storage 1");
deepEqual(events[1].target.result, "Data",
"Check uploaded document in sub storage 1");
}).fail(unexpectedError).always(start);
});
test("Get", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "get1",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "get2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.get({"_id": "three"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "three",
"message": "Unable to get document",
"method": "get",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing document");
return jio.post({
"_id": "three",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.get({"_id": "three"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "three",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Get posted document");
return jio.putAttachment({
"_id": "three",
"_attachment": "my_attachment",
"_data": "My Data",
"_content_type": "text/plain"
});
}).then(function () {
return jio.get({"_id": "three"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "three",
"_underscored_meta": "uvalue",
"meta": "data",
"_attachments": {
"my_attachment": {
"length": 7,
"content_type": "text/plain"
}
}
}, "Get document with attachment informations");
}).fail(unexpectedError).always(start);
});
test("GetAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "getAttachment",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"application_name": "getAttachment2",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.getAttachment({
"_id": "four",
"_attachment": "my_attachment"
}))
.then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "four",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get attachment from missing document -> 404 Not Found");
return jio.post({
"_id": "four",
"_underscored_meta": "uvalue",
"meta": "data"
});
})
.then(function () {
return reverse(jio.getAttachment({
"_id": "four",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "four",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Get missing attachment from document");
return jio.putAttachment({
"_id": "four",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
})
.then(function () {
return jio.getAttachment({
"_id": "four",
"_attachment": "my_attachment"
});
}).then(function (answer) {
return tool.readBlobAsBinaryString(answer.data);
}).then(function (event) {
deepEqual(event.target.result, "My Data", "Get attachment");
})
.fail(unexpectedError).always(start);
});
test("RemoveAttachment", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"mode": "memory"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y",
"mode": "memory"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.removeAttachment({
"_id": "five",
"_attachment": "my_attachment"
})).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "five",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing document",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove attachment from inexistent document -> 404 Not Found");
return jio.post({
"_id": "five",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return reverse(jio.removeAttachment({
"_id": "five",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "five",
"message": "Unable to remove attachment",
"method": "removeAttachment",
"reason": "missing attachment",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove inexistent attachment -> 404 Not Found");
return jio.putAttachment({
"_id": "five",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
})
.then(function () {
return jio.removeAttachment({
"_id": "five",
"_attachment": "my_attachment"
});
})
.then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"id": "five",
"method": "removeAttachment",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove attachment");
return jio.get({"_id": "five"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "five",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return reverse(jio.getAttachment({
"_id": "five",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "five",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
})
.fail(unexpectedError).always(start);
});
test("Remove", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
reverse(jio.remove({"_id": "six"})).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "six",
"message": "Unable to remove document",
"method": "remove",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Remove missing document -> 404 Not Found");
return jio.post({
"_id": "six",
"_underscored_meta": "uvalue",
"meta": "data"
});
}).then(function () {
return jio.putAttachment({
"_id": "six",
"_attachment": "my_attachment",
"_data": "My Data",
"_mimetype": "text/plain"
});
}).then(function () {
return jio.remove({"_id": "six"});
}).then(function (answer) {
deepEqual(answer, {
"id": "six",
"method": "remove",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Remove document");
return reverse(jio.getAttachment({
"_id": "six",
"_attachment": "my_attachment"
}));
}).then(function (answer) {
deepEqual(answer, {
"attachment": "my_attachment",
"error": "not_found",
"id": "six",
"message": "Unable to get attachment",
"method": "getAttachment",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check attachment -> 404 Not Found");
return reverse(jio.get({"_id": "six"}));
}).then(function (answer) {
deepEqual(answer, {
"error": "not_found",
"id": "six",
"message": "Unable to get document",
"method": "get",
"reason": "Not Found",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check document -> 404 Not Found");
}).fail(unexpectedError).always(start);
});
test("Put", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucketsplit",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucketsplit_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
jio.put({
"_id": "seven",
"_underscored_meta": "uvalue",
"meta": "data"
}).then(function (answer) {
deepEqual(answer, {
"id": "seven",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put new document");
return jio.get({"_id": "seven"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "seven",
"_underscored_meta": "uvalue",
"meta": "data"
}, "Check document");
return jio.put({
"_id": "seven",
"_underscored_meta": "uvalue",
"meow": "dog"
});
}).then(function (answer) {
deepEqual(answer, {
"id": "seven",
"method": "put",
"result": "success",
"status": 204,
"statusText": "No Content"
}, "Put same document again");
return jio.get({"_id": "seven"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "seven",
"_underscored_meta": "uvalue",
"meow": "dog"
}, "Get document for check");
}).fail(unexpectedError).always(start);
});
test("AllDocs", function () {
var shared = {}, jio;
shared.workspace = {};
shared.s3_storage_description1 = {
"type": "s3",
"server": "jiobucket_alldocs",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
shared.s3_storage_description2 = {
"type": "s3",
"server": "jiobucket_alldocs_bis",
"AWSIdentifier": "AKIAJLNYGVLTV66RHPEQ",
"password": "/YHoa5r2X6EUHfvP31jdYx6t75h81pAjIZ4Mt94y"
};
jio = jIO.createJIO({
"type": "split",
"storage_list": [
shared.s3_storage_description1,
shared.s3_storage_description2
]
}, {"workspace": shared.workspace});
stop();
function prepareDatabase() {
var i, do_list = [];
function post(i) {
return function () {
return jio.post({
"_id": "doc" + i,
"_underscored_meta": "uvalue" + i,
"meta": "data" + i
});
};
}
function putAttachment(i) {
return function () {
return jio.putAttachment({
"_id": "doc" + i,
"_attachment": "my_attachment" + i,
"_data": "My Data" + i,
"_content_type": "text/plain"
});
};
}
for (i = 0; i < 5; i += 1) {
do_list.push(post(i));
}
for (i = 0; i < 2; i += 1) {
do_list.push(putAttachment(i));
}
return sequence(do_list);
}
prepareDatabase().then(function () {
return jio.get({"_id": "doc1"});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": "doc1",
"_underscored_meta": "uvalue1",
"meta": "data1",
"_attachments": {
"my_attachment1": {
"length": 8,
"content_type": "text/plain"
}
}
}, "Check document");
return jio.allDocs();
}).then(function (answer) {
answer.data.rows.sort(function (a, b) {
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
});
deepEqual(answer.data, {
"total_rows": 5,
"rows": [
{
"id": "doc0",
"value": {}
},
{
"id": "doc1",
"value": {}
},
{
"id": "doc2",
"value": {}
},
{
"id": "doc3",
"value": {}
},
{
"id": "doc4",
"value": {}
}]
}, "AllDocs with document ids only");
}).fail(unexpectedError).always(start);
});
}));
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