Commit d40e0e8d authored by Tristan Cavelier's avatar Tristan Cavelier

revisionstorage.tests.js post method done

parent 4ad887e3
/*jslint indent: 2, maxlen: 80, nomen: true */
/*global define, jIO, jio_tests, hex_sha256, window, test, ok, deepEqual, sinon,
expect */
/*global define, jIO, test_util, hex_sha256, RSVP, test, ok, deepEqual, start,
stop, module */
// define([module_name], [dependencies], module);
(function (dependencies, module) {
......@@ -8,56 +8,23 @@
if (typeof define === 'function' && define.amd) {
return define(dependencies, module);
}
module(jIO, jio_tests, {hex_sha256: hex_sha256});
}(['jio', 'jio_tests', 'sha256', 'localstorage', 'revisionstorage'], function (
jIO,
util,
sha256
) {
module(jIO, test_util, {hex_sha256: hex_sha256}, RSVP);
}([
'jio',
'test_util',
'sha256',
'rsvp',
'localstorage',
'revisionstorage'
], function (jIO, util, sha256, RSVP) {
"use strict";
//////////////////////////////////////////////////////////////////////////////
// Tools
/**
* Clones all native object in deep. Managed types: Object, Array, String,
* Number, Boolean, Function, null.
*
* @param {A} object The object to clone
* @return {A} The cloned object
*/
function deepClone(object) {
var i, cloned;
if (Array.isArray(object)) {
cloned = [];
for (i = 0; i < object.length; i += 1) {
cloned[i] = deepClone(object[i]);
}
return cloned;
}
if (typeof object === "object") {
cloned = {};
for (i in object) {
if (object.hasOwnProperty(i)) {
cloned[i] = deepClone(object[i]);
}
}
return cloned;
}
return object;
}
function generateTools() {
return {
clock: sinon.useFakeTimers(),
spy: util.ospy,
tick: util.otick
};
}
function generateRevisionHash(doc, revisions, deleted_flag) {
var string;
doc = deepClone(doc);
doc = jIO.util.deepClone(doc);
delete doc._rev;
delete doc._revs;
delete doc._revs_info;
......@@ -66,6 +33,30 @@
return sha256.hex_sha256(string);
}
function isRevision(revision) {
return (/^[0-9]+-[0-9a-zA-Z]+$/).test(revision);
}
function success(promise) {
return new RSVP.Promise(function (resolve, reject, notify) {
/*jslint unparam: true*/
promise.then(resolve, resolve, notify);
}, function () {
promise.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");
}
}
//////////////////////////////////////////////////////////////////////////////
// Tests
......@@ -73,1318 +64,1403 @@
test("Post", function () {
var o = generateTools();
var shared = {}, jio, jio_local;
shared.workspace = {};
shared.local_storage_description = {
"type": "local",
"username": "revision post",
"mode": "memory"
//"mode": "localStorage"
};
o.jio = jIO.newJio({
jio = jIO.createJIO({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "urevpost",
"application_name": "arevpost"
}
"sub_storage": shared.local_storage_description
}, {"workspace": shared.workspace});
jio_local = jIO.createJIO(shared.local_storage_description, {
"workspace": shared.workspace
});
o.localpath = "jio/localstorage/urevpost/arevpost";
stop();
// post without id
o.revisions = {"start": 0, "ids": []};
o.spy(o, "status", undefined, "Post without id");
o.jio.post({}, function (err, response) {
o.f.apply(arguments);
o.uuid = (err || response).id;
ok(util.isUuid(o.uuid), "Uuid should look like " +
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx : " + o.uuid);
});
o.tick(o);
o.rev = "1-" + generateRevisionHash({"_id": o.uuid}, o.revisions);
// check document
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/" + o.uuid + "." + o.rev),
{"_id": o.uuid + "." + o.rev},
"Check document"
);
// check document tree
o.doc_tree = {
"_id": o.uuid + ".revision_tree.json",
"children": [{
"rev": o.rev,
"status": "available",
"children": []
}]
};
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/" + o.uuid + ".revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// post non empty document
o.doc = {"_id": "post1", "title": "myPost1"};
o.rev = "1-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"ok": true, "id": "post1", "rev": o.rev}, "Post");
o.jio.post(o.doc, o.f);
o.tick(o);
// check document
o.doc._id = "post1." + o.rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/post1." + o.rev),
o.doc,
"Check document"
);
// check document tree
o.doc_tree._id = "post1.revision_tree.json";
o.doc_tree.children[0] = {
"rev": o.rev,
"status": "available",
"children": []
};
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/post1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// post and document already exists
o.doc = {"_id": "post1", "title": "myPost2"};
o.rev = "1-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {
"ok": true,
"id": "post1",
"rev": o.rev
}, "Post and document already exists");
o.jio.post(o.doc, o.f);
o.tick(o);
// check document
o.doc._id = "post1." + o.rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/post1." + o.rev),
o.doc,
"Check document"
);
// check document tree
o.doc_tree._id = "post1.revision_tree.json";
o.doc_tree.children.unshift({
"rev": o.rev,
"status": "available",
"children": []
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/post1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// post + revision
o.doc = {"_id": "post1", "_rev": o.rev, "title": "myPost2"};
o.revisions = {"start": 1, "ids": [o.rev.split('-')[1]]};
o.rev = "2-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"ok": true, "id": "post1", "rev": o.rev},
"Post + revision");
o.jio.post(o.doc, o.f);
o.tick(o);
// // keep_revision_history
// ok (false, "keep_revision_history Option Not Implemented");
// check document
o.doc._id = "post1." + o.rev;
delete o.doc._rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/post1." + o.rev),
o.doc,
"Check document"
);
// check document tree
o.doc_tree._id = "post1.revision_tree.json";
o.doc_tree.children[0].children.unshift({
"rev": o.rev,
"status": "available",
"children": []
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/post1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// add attachment
o.doc._attachments = {
"attachment_test": {
"length": 35,
"digest": "A",
"content_type": "oh/yeah"
}
};
util.jsonlocalstorage.setItem(o.localpath + "/post1." + o.rev, o.doc);
util.jsonlocalstorage.setItem(
o.localpath + "/post1." + o.rev + "/attachment_test",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
);
// post + attachment copy
o.doc = {"_id": "post1", "_rev": o.rev, "title": "myPost2"};
o.revisions = {
"start": 2,
"ids": [o.rev.split('-')[1], o.revisions.ids[0]]
};
o.rev = "3-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"ok": true, "id": "post1", "rev": o.rev},
"Post + attachment copy");
o.jio.post(o.doc, o.f);
o.tick(o);
// check attachment
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/post1." + o.rev +
"/attachment_test"),
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"Check Attachment"
);
// check document tree
o.doc_tree._id = "post1.revision_tree.json";
o.doc_tree.children[0].children[0].children.unshift({
"rev": o.rev,
"status": "available",
"children": []
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/post1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// post + wrong revision
o.doc = {"_id": "post1", "_rev": "3-wr3", "title": "myPost3"};
o.revisions = {"start": 3, "ids": ["wr3"]};
o.rev = "4-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"id": "post1", "ok": true, "rev": o.rev},
"Post + wrong revision");
o.jio.post(o.doc, o.f);
o.tick(o);
// check document
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/post1.3-wr3"),
null,
"Check document"
);
// check document
o.doc._id = "post1." + o.rev;
delete o.doc._rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/post1." + o.rev),
o.doc,
"Check document"
);
// check document tree
o.doc_tree._id = "post1.revision_tree.json";
o.doc_tree.children.unshift({
"rev": "3-wr3",
"status": "missing",
"children": [{
"rev": o.rev,
shared.revisions = {"start": 0, "ids": []};
jio.post({}).then(function (response) {
shared.uuid = response.id;
response.id = "<uuid>";
shared.rev = response.rev;
response.rev = "<rev>";
ok(util.isUuid(shared.uuid), "Uuid should look like " +
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx : " + shared.uuid);
ok(isRevision(shared.rev), "Revision should look like " +
"x-xxxxxxxxxxxxxxxxxxxxxxxxx... : " + shared.rev);
deepEqual(
shared.rev,
"1-" + generateRevisionHash({"_id": shared.uuid}, shared.revisions),
"Check revision value"
);
deepEqual(response, {
"id": "<uuid>",
"rev": "<rev>",
"method": "post",
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post without id");
return jio_local.get({"_id": shared.uuid + "." + shared.rev});
}).then(function (answer) {
deepEqual(answer.data, {
"_id": shared.uuid + "." + shared.rev
}, "Check document");
return jio_local.get({"_id": shared.uuid + ".revision_tree.json"});
}).then(function (answer) {
shared.doc_tree = {
"_id": shared.uuid + ".revision_tree.json",
"children": JSON.stringify([{
"rev": shared.rev,
"status": "available",
"children": []
}])
};
deepEqual(answer.data, shared.doc_tree, "Check document tree");
// post non empty document
shared.doc = {"_id": "post1", "title": "myPost1"};
shared.rev = "1-" + generateRevisionHash(shared.doc, shared.revisions);
return jio.post(shared.doc);
}).then(function (answer) {
deepEqual(answer, {
"id": "post1",
"method": "post",
"result": "success",
"rev": "1-eedaf5235af91978a06d0b0e68b1c16adbc539" +
"5bb9bd4a0cfd632fe03f9d8ef3",
"status": 201,
"statusText": "Created"
}, "Post");
// check document
shared.doc._id = "post1." + shared.rev;
return jio_local.get(shared.doc);
}).then(function (answer) {
deepEqual(answer.data, {
"_id": shared.doc._id,
"title": "myPost1"
}, "Check document");
// check document tree
shared.doc_tree._id = "post1.revision_tree.json";
shared.doc_tree.children = JSON.parse(shared.doc_tree.children);
shared.doc_tree.children[0] = {
"rev": shared.rev,
"status": "available",
"children": []
}]
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/post1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
util.closeAndcleanUpJio(o.jio);
});
};
shared.doc_tree.children = JSON.stringify(shared.doc_tree.children);
test("Put", function () {
return jio_local.get(shared.doc_tree);
var o = generateTools();
}).then(function (answer) {
o.jio = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "urevput",
"application_name": "arevput"
}
});
o.localpath = "jio/localstorage/urevput/arevput";
// put without id
// error 20 -> document id required
o.spy(o, "status", 20, "Put without id");
o.jio.put({}, o.f);
o.tick(o);
// put non empty document
o.doc = {"_id": "put1", "title": "myPut1"};
o.revisions = {"start": 0, "ids": []};
o.rev = "1-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"ok": true, "id": "put1", "rev": o.rev},
"Creates a document");
o.jio.put(o.doc, o.f);
o.tick(o);
// check document
o.doc._id = "put1." + o.rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
o.doc,
"Check document"
);
// check document tree
o.doc_tree = {
"_id": "put1.revision_tree.json",
"children": [{
"rev": o.rev,
"status": "available",
"children": []
}]
};
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/put1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// put without rev and document already exists
o.doc = {"_id": "put1", "title": "myPut2"};
o.rev = "1-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"ok": true, "id": "put1", "rev": o.rev},
"Put same document without revision");
o.jio.put(o.doc, o.f);
o.tick(o);
o.doc_tree.children.unshift({
"rev": o.rev,
"status": "available",
"children": []
});
deepEqual(answer.data, shared.doc_tree, "Check document tree");
// put + revision
o.doc = {"_id": "put1", "_rev": o.rev, "title": "myPut2"};
o.revisions = {"start": 1, "ids": [o.rev.split('-')[1]]};
o.rev = "2-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"id": "put1", "ok": true, "rev": o.rev},
"Put + revision");
o.jio.put(o.doc, o.f);
o.tick(o);
// check document
o.doc._id = "put1." + o.rev;
delete o.doc._rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
o.doc,
"Check document"
);
// check document tree
o.doc_tree.children[0].children.unshift({
"rev": o.rev,
"status": "available",
"children": []
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/put1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// put + wrong revision
o.doc = {"_id": "put1", "_rev": "3-wr3", "title": "myPut3"};
o.revisions = {"start": 3, "ids": ["wr3"]};
o.rev = "4-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"id": "put1", "ok": true, "rev": o.rev},
"Put + wrong revision");
o.jio.put(o.doc, o.f);
o.tick(o);
// check document
o.doc._id = "put1." + o.rev;
delete o.doc._rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
o.doc,
"Check document"
);
// check document tree
o.doc_tree.children.unshift({
"rev": "3-wr3",
"status": "missing",
"children": [{
"rev": o.rev,
"status": "available",
"children": []
}]
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/put1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// put + revision history
o.doc = {
"_id": "put1",
//"_revs": ["3-rh3", "2-rh2", "1-rh1"], // same as below
"_revs": {"start": 3, "ids": ["rh3", "rh2", "rh1"]},
"title": "myPut3"
};
o.spy(o, "value", {"id": "put1", "ok": true, "rev": "3-rh3"},
"Put + revision history");
o.jio.put(o.doc, o.f);
o.tick(o);
// check document
o.doc._id = "put1.3-rh3";
delete o.doc._revs;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/put1.3-rh3"),
o.doc,
"Check document"
);
// check document tree
o.doc_tree.children.unshift({
"rev": "1-rh1",
"status": "missing",
"children": [{
"rev": "2-rh2",
"status": "missing",
"children": [{
"rev": "3-rh3",
"status": "available",
"children": []
}]
}]
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/put1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// add attachment
o.doc._attachments = {
"att1": {
"length": 1,
"content_type": "text/plain",
"digest": "md5-0cc175b9c0f1b6a831c399e269772661"
},
"att2": {
"length": 2,
"content_type": "dont/care",
"digest": "md5-5360af35bde9ebd8f01f492dc059593c"
}
};
util.jsonlocalstorage.setItem(o.localpath + "/put1.3-rh3", o.doc);
util.jsonlocalstorage.setItem(o.localpath + "/put1.3-rh3/att1", "a");
util.jsonlocalstorage.setItem(o.localpath + "/put1.3-rh3/att2", "bc");
// put + revision with attachment
o.attachments = o.doc._attachments;
o.doc = {"_id": "put1", "_rev": "3-rh3", "title": "myPut4"};
o.revisions = {"start": 3, "ids": ["rh3", "rh2", "rh1"]};
o.rev = "4-" + generateRevisionHash(o.doc, o.revisions);
o.spy(o, "value", {"id": "put1", "ok": true, "rev": o.rev},
"Put + revision (document contains attachments)");
o.jio.put(o.doc, o.f);
o.tick(o);
// check document
o.doc._id = "put1." + o.rev;
o.doc._attachments = o.attachments;
delete o.doc._rev;
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
o.doc,
"Check document"
);
// check attachments
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev + "/att1"),
"a",
"Check Attachment"
);
deepEqual(
util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev + "/att2"),
"bc",
"Check Attachment"
);
// check document tree
o.doc_tree.children[0].children[0].children[0].children.unshift({
"rev": o.rev,
"status": "available",
"children": []
});
deepEqual(
util.jsonlocalstorage.getItem(
o.localpath + "/put1.revision_tree.json"
),
o.doc_tree,
"Check document tree"
);
// post and document already exists
shared.doc = {"_id": "post1", "title": "myPost2"};
shared.rev = "1-" + generateRevisionHash(shared.doc, shared.revisions);
return jio.post(shared.doc);
util.closeAndcleanUpJio(o.jio);
}).then(function (answer) {
});
deepEqual(answer, {
"id": "post1",
"method": "post",
"result": "success",
"rev": shared.rev,
"status": 201,
"statusText": "Created"
}, "Post and document already exists");
test("Put Attachment", function () {
// check document
shared.doc._id = "post1." + shared.rev;
return jio_local.get(shared.doc);
var o = generateTools();
}).then(function (answer) {
o.jio = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "urevputattmt",
"application_name": "arevputattmt"
}
});
deepEqual(answer.data, shared.doc, "Check document");
// putAttachment without doc id
// error 20 -> document id required
o.spy(o, "status", 20, "PutAttachment without doc id" +
" -> 20 document id required");
o.jio.putAttachment({}, o.f);
o.tick(o);
// putAttachment without attachment id
// erorr 22 -> attachment id required
o.spy(o, "status", 22, "PutAttachment without attachment id" +
" -> 22 attachment id required");
o.jio.putAttachment({"_id": "putattmt1"}, o.f);
o.tick(o);
// putAttachment without document
o.revisions = {"start": 0, "ids": []};
o.rev_hash = generateRevisionHash({"_id": "doc1", "_attachment": "attmt1"},
o.revisions);
o.rev = "1-" + o.rev_hash;
o.spy(o, "value",
{"ok": true, "id": "doc1", "attachment": "attmt1", "rev": o.rev},
"PutAttachment without document, without data");
o.jio.putAttachment({"_id": "doc1", "_attachment": "attmt1"}, o.f);
o.tick(o);
// check document
deepEqual(
util.jsonlocalstorage.getItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
),
{
"_id": "doc1." + o.rev,
"_attachments": {
"attmt1": {
"length": 0,
// md5("")
"digest": "md5-d41d8cd98f00b204e9800998ecf8427e"
}
}
},
"Check document"
);
// check attachment
deepEqual(util.jsonlocalstorage.getItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
+ "/attmt1"
), "", "Check attachment");
// adding a metadata to the document
o.doc = util.jsonlocalstorage.getItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
);
o.doc.title = "My Title";
util.jsonlocalstorage.setItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev,
o.doc
);
// update attachment
o.prev_rev = o.rev;
o.revisions = {"start": 1, "ids": [o.rev_hash]};
o.rev_hash = generateRevisionHash({
"_id": "doc1",
"_data": "abc",
"_attachment": "attmt1",
}, o.revisions);
o.rev = "2-" + o.rev_hash;
o.spy(o, "value",
{"ok": true, "id": "doc1", "attachment": "attmt1", "rev": o.rev},
"Update Attachment, with data");
o.jio.putAttachment({
"_id": "doc1",
"_data": "abc",
"_attachment": "attmt1",
"_rev": o.prev_rev
}, o.f);
o.tick(o);
// check document
deepEqual(
util.jsonlocalstorage.getItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
),
{
"_id": "doc1." + o.rev,
"title": "My Title",
"_attachments": {
"attmt1": {
"length": 3,
// md5("abc")
"digest": "md5-900150983cd24fb0d6963f7d28e17f72"
}
}
},
"Check document"
);
// check attachment
deepEqual(util.jsonlocalstorage.getItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev +
"/attmt1"
), "abc", "Check attachment");
// putAttachment new attachment
o.prev_rev = o.rev;
o.revisions = {"start": 2, "ids": [o.rev_hash, o.revisions.ids[0]]};
o.rev_hash = generateRevisionHash({
"_id": "doc1",
"_data": "def",
"_attachment": "attmt2",
}, o.revisions);
o.rev = "3-" + o.rev_hash;
o.spy(o, "value",
{"ok": true, "id": "doc1", "attachment": "attmt2", "rev": o.rev},
"PutAttachment without document, without data");
o.jio.putAttachment({
"_id": "doc1",
"_data": "def",
"_attachment": "attmt2",
"_rev": o.prev_rev
}, o.f);
o.tick(o);
// check document
deepEqual(
util.jsonlocalstorage.getItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
),
{
"_id": "doc1." + o.rev,
"title": "My Title",
"_attachments": {
"attmt1": {
"length": 3,
"digest": "md5-900150983cd24fb0d6963f7d28e17f72"
},
"attmt2": {
"length": 3,
// md5("def")
"digest": "md5-4ed9407630eb1000c0f6b63842defa7d"
}
}
},
"Check document"
);
// check attachment
deepEqual(util.jsonlocalstorage.getItem(
"jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev +
"/attmt2"
), "def", "Check attachment");
util.closeAndcleanUpJio(o.jio);
// check document tree
shared.doc_tree._id = "post1.revision_tree.json";
shared.doc_tree.children = JSON.parse(shared.doc_tree.children);
shared.doc_tree.children.unshift({
"rev": shared.rev,
"status": "available",
"children": []
});
shared.doc_tree.children = JSON.stringify(shared.doc_tree.children);
});
return jio_local.get(shared.doc_tree);
test("Get", function () {
}).then(function (answer) {
var o = generateTools();
deepEqual(answer.data, shared.doc_tree, "Check document tree");
o.jio = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "urevget",
"application_name": "arevget"
}
});
o.localpath = "jio/localstorage/urevget/arevget";
// get inexistent document
o.spy(o, "status", 404, "Get inexistent document (winner)" +
" -> 404 Not Found");
o.jio.get({"_id": "get1"}, o.f);
o.tick(o);
// get inexistent attachment
o.spy(o, "status", 404, "Get inexistent attachment (winner)" +
" -> 404 Not Found");
o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o);
// adding a document
o.doctree = {"children": [{
"rev": "1-rev1",
"status": "available",
"children": []
}]};
o.doc_myget1 = {"_id": "get1.1-rev1", "title": "myGet1"};
util.jsonlocalstorage.setItem(
o.localpath + "/get1.revision_tree.json",
o.doctree
);
util.jsonlocalstorage.setItem(o.localpath + "/get1.1-rev1", o.doc_myget1);
// get document
o.doc_myget1_cloned = deepClone(o.doc_myget1);
o.doc_myget1_cloned._id = "get1";
o.doc_myget1_cloned._rev = "1-rev1";
o.doc_myget1_cloned._revisions = {"start": 1, "ids": ["rev1"]};
o.doc_myget1_cloned._revs_info = [{
"rev": "1-rev1",
"status": "available"
}];
o.spy(o, "value", o.doc_myget1_cloned, "Get document (winner)");
o.jio.get({"_id": "get1"}, {
"revs_info": true,
"revs": true,
"conflicts": true
}, o.f);
o.tick(o);
// adding two documents
o.doctree = {"children": [{
"rev": "1-rev1",
"status": "available",
"children": []
}, {
"rev": "1-rev2",
"status": "available",
"children": [{
"rev": "2-rev3",
"status": "available",
"children": []
}]
}]};
o.doc_myget2 = {"_id": "get1.1-rev2", "title": "myGet2"};
o.doc_myget3 = {"_id": "get1.2-rev3", "title": "myGet3"};
util.jsonlocalstorage.setItem(
o.localpath + "/get1.revision_tree.json",
o.doctree
);
util.jsonlocalstorage.setItem(o.localpath + "/get1.1-rev2", o.doc_myget2);
util.jsonlocalstorage.setItem(o.localpath + "/get1.2-rev3", o.doc_myget3);
// get document
o.doc_myget3_cloned = deepClone(o.doc_myget3);
o.doc_myget3_cloned._id = "get1";
o.doc_myget3_cloned._rev = "2-rev3";
o.doc_myget3_cloned._revisions = {"start": 2, "ids": ["rev3", "rev2"]};
o.doc_myget3_cloned._revs_info = [{
"rev": "2-rev3",
"status": "available"
}, {
"rev": "1-rev2",
"status": "available"
}];
o.doc_myget3_cloned._conflicts = ["1-rev1"];
o.spy(o, "value", o.doc_myget3_cloned,
"Get document (winner, after posting another one)");
o.jio.get({"_id": "get1"},
{"revs_info": true, "revs": true, "conflicts": true},
o.f);
o.tick(o);
// get inexistent specific document
o.spy(o, "status", 404, "Get document (inexistent specific revision)" +
" -> 404 Not Found");
o.jio.get({"_id": "get1", "_rev": "1-rev0"}, {
"revs_info": true,
"revs": true,
"conflicts": true,
}, o.f);
o.tick(o);
// get specific document
o.doc_myget2_cloned = deepClone(o.doc_myget2);
o.doc_myget2_cloned._id = "get1";
o.doc_myget2_cloned._rev = "1-rev2";
o.doc_myget2_cloned._revisions = {"start": 1, "ids": ["rev2"]};
o.doc_myget2_cloned._revs_info = [{
"rev": "1-rev2",
"status": "available"
}];
o.doc_myget2_cloned._conflicts = ["1-rev1"];
o.spy(o, "value", o.doc_myget2_cloned, "Get document (specific revision)");
o.jio.get({"_id": "get1", "_rev": "1-rev2"}, {
"revs_info": true,
"revs": true,
"conflicts": true,
}, o.f);
o.tick(o);
// adding an attachment
o.attmt_myget3 = {
"get2": {
"length": 3,
"digest": "md5-dontcare",
"content_type": "oh/yeah"
}
};
o.doc_myget3._attachments = o.attmt_myget3;
util.jsonlocalstorage.setItem(o.localpath + "/get1.2-rev3", o.doc_myget3);
util.jsonlocalstorage.setItem(o.localpath + "/get1.2-rev3/get2", "abc");
// get attachment winner
o.spy(o, "value", "abc", "Get attachment (winner)");
o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
o.tick(o);
// get inexistent attachment specific rev
o.spy(o, "status", 404, "Get inexistent attachment (specific revision)" +
" -> 404 Not Found");
o.jio.getAttachment({
"_id": "get1",
"_attachment": "get2",
"_rev": "1-rev1"
}, {
"revs_info": true,
"revs": true,
"conflicts": true,
}, o.f);
o.tick(o);
// get attachment specific rev
o.spy(o, "value", "abc", "Get attachment (specific revision)");
o.jio.getAttachment({
"_id": "get1",
"_attachment": "get2",
"_rev": "2-rev3"
}, {
"revs_info": true,
"revs": true,
"conflicts": true,
}, o.f);
o.tick(o);
// get document with attachment (specific revision)
delete o.doc_myget2_cloned._attachments;
o.spy(o, "value", o.doc_myget2_cloned,
"Get document which have an attachment (specific revision)");
o.jio.get({"_id": "get1", "_rev": "1-rev2"}, {
"revs_info": true,
"revs": true,
"conflicts": true
}, o.f);
o.tick(o);
// get document with attachment (winner)
o.doc_myget3_cloned._attachments = o.attmt_myget3;
o.spy(o, "value", o.doc_myget3_cloned,
"Get document which have an attachment (winner)");
o.jio.get({"_id": "get1"},
{"revs_info": true, "revs": true, "conflicts": true},
o.f);
o.tick(o);
util.closeAndcleanUpJio(o.jio);
// post + revision
shared.doc = {"_id": "post1", "_rev": shared.rev, "title": "myPost2"};
shared.revisions = {"start": 1, "ids": [shared.rev.split('-')[1]]};
shared.rev = "2-" + generateRevisionHash(shared.doc, shared.revisions);
return jio.post(shared.doc);
});
}).then(function (answer) {
test("Remove", function () {
deepEqual(answer, {
"id": "post1",
"method": "post",
"result": "success",
"rev": shared.rev,
"status": 201,
"statusText": "Created" // XXX should be 204 no content
}, "Post + revision");
var o = generateTools();
// // keep_revision_history
// ok (false, "keep_revision_history Option Not Implemented");
o.jio = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "urevrem",
"application_name": "arevrem"
}
});
o.localpath = "jio/localstorage/urevrem/arevrem";
// 1. remove document without revision
o.spy(o, "status", 409, "Remove document without revision " +
"-> 409 Conflict");
o.jio.remove({"_id": "remove1"}, o.f);
o.tick(o);
// 2. remove attachment without revision
o.spy(o, "status", 409, "Remove attachment without revision " +
"-> 409 Conflict");
o.jio.removeAttachment({"_id": "remove1", "_attachment": "remove2"}, o.f);
o.tick(o);
// adding a document with attachments
o.doc_myremove1 = {
"_id": "remove1.1-veryoldrev",
"title": "myRemove1"
};
// check document
shared.doc._id = "post1." + shared.rev;
delete shared.doc._rev;
return jio_local.get(shared.doc);
util.jsonlocalstorage.setItem(o.localpath + "/remove1.1-veryoldrev",
o.doc_myremove1);
}).then(function (answer) {
o.doc_myremove1._id = "remove1.2-oldrev";
o.attachment_remove2 = {
"length": 3,
"digest": "md5-dontcare",
"content_type": "oh/yeah"
};
o.attachment_remove3 = {
"length": 5,
"digest": "md5-865f5cc7fbd7854902eae9d8211f178a",
"content_type": "he/ho"
};
o.doc_myremove1._attachments = {
"remove2": o.attachment_remove2,
"remove3": o.attachment_remove3
};
deepEqual(answer.data, shared.doc, "Check document");
util.jsonlocalstorage.setItem(o.localpath + "/remove1.2-oldrev",
o.doc_myremove1);
util.jsonlocalstorage.setItem(
o.localpath + "/remove1.2-oldrev/remove2",
"abc"
);
util.jsonlocalstorage.setItem(
o.localpath + "/remove1.2-oldrev/remove3",
"defgh"
);
// add document tree
o.doctree = {
"children": [{
"rev": "1-veryoldrev",
// check document tree
shared.doc_tree._id = "post1.revision_tree.json";
shared.doc_tree.children = JSON.parse(shared.doc_tree.children);
shared.doc_tree.children[0].children.unshift({
"rev": shared.rev,
"status": "available",
"children": []
});
shared.doc_tree.children = JSON.stringify(shared.doc_tree.children);
return jio_local.get(shared.doc_tree);
}).then(function (answer) {
deepEqual(answer.data, shared.doc_tree, "Check document tree");
// add attachment
return jio_local.putAttachment({
"_id": "post1." + shared.rev,
"_attachment": "attachment_test",
"_data": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"_mimetype": "oh/yeah"
});
}).then(function () {
// post + attachment copy
shared.doc = {"_id": "post1", "_rev": shared.rev, "title": "myPost2"};
shared.revisions = {
"start": 2,
"ids": [shared.rev.split('-')[1], shared.revisions.ids[0]]
};
shared.rev = "3-" + generateRevisionHash(shared.doc, shared.revisions);
return jio.post(shared.doc);
}).then(function (answer) {
deepEqual(answer, {
"id": "post1",
"method": "post",
"result": "success",
"rev": shared.rev,
"status": 201,
"statusText": "Created"
}, "Post + attachment copy");
// check attachment
return jio_local.getAttachment({
"_id": "post1." + shared.rev,
"_attachment": "attachment_test"
});
}).then(function (answer) {
return jIO.util.readBlobAsBinaryString(answer.data);
}).then(function (event) {
deepEqual(event.target.result, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"Check Attachment");
// check document tree
shared.doc_tree._id = "post1.revision_tree.json";
shared.doc_tree.children = JSON.parse(shared.doc_tree.children);
shared.doc_tree.children[0].children[0].children.unshift({
"rev": shared.rev,
"status": "available",
"children": []
});
shared.doc_tree.children = JSON.stringify(shared.doc_tree.children);
return jio_local.get({"_id": shared.doc_tree._id});
}).then(function (answer) {
deepEqual(
answer.data,
shared.doc_tree,
"Check document tree"
);
// post + wrong revision
shared.doc = {"_id": "post1", "_rev": "3-wr3", "title": "myPost3"};
shared.revisions = {"start": 3, "ids": ["wr3"]};
shared.rev = "4-" + generateRevisionHash(shared.doc, shared.revisions);
return jio.post(shared.doc);
}).then(function (answer) {
deepEqual(answer, {
"id": "post1",
"method": "post",
"rev": shared.rev,
"result": "success",
"status": 201,
"statusText": "Created"
}, "Post + wrong revision");
return success(jio_local.get({"_id": "post1.3-wr3"}));
}).then(function (answer) {
// check document
deepEqual(answer, {
"error": "not_found",
"id": "post1.3-wr3",
"message": "Cannot find document",
"method": "get",
"reason": "missing",
"result": "error",
"status": 404,
"statusText": "Not Found"
}, "Check document");
// check document
shared.doc._id = "post1." + shared.rev;
delete shared.doc._rev;
return jio_local.get({"_id": shared.doc._id});
}).then(function (answer) {
deepEqual(answer.data, shared.doc, "Check document");
// check document tree
shared.doc_tree._id = "post1.revision_tree.json";
shared.doc_tree.children = JSON.parse(shared.doc_tree.children);
shared.doc_tree.children.unshift({
"rev": "3-wr3",
"status": "missing",
"children": [{
"rev": "2-oldrev",
"rev": shared.rev,
"status": "available",
"children": []
}]
}]
};
util.jsonlocalstorage.setItem(o.localpath + "/remove1.revision_tree.json",
o.doctree);
// 3. remove inexistent attachment
o.spy(o, "status", 404, "Remove inexistent attachment -> 404 Not Found");
o.jio.removeAttachment({
"_id": "remove1",
"_attachment": "remove0",
"_rev": "2-oldrev"
}, o.f);
o.tick(o);
// 4. remove existing attachment
o.rev_hash = generateRevisionHash({
"_id": "remove1",
"_attachment": "remove2",
}, {"start": 2, "ids": ["oldrev", "veryoldrev"]});
o.spy(o, "value", {
"ok": true,
"id": "remove1",
"attachment": "remove2",
"rev": "3-" + o.rev_hash
}, "Remove existing attachment");
o.jio.removeAttachment({
"_id": "remove1",
"_attachment": "remove2",
"_rev": "2-oldrev"
}, o.f);
o.tick(o);
o.doctree = {
"_id": "remove1.revision_tree.json",
"children": [{
"rev": "1-veryoldrev",
"status": "available",
"children": [{
"rev": "2-oldrev",
"status": "available",
"children": [{
"rev": "3-" + o.rev_hash,
"status": "available",
"children": []
}]
}]
}]
};
});
shared.doc_tree.children = JSON.stringify(shared.doc_tree.children);
// 5. check if document tree has been updated correctly
deepEqual(util.jsonlocalstorage.getItem(
o.localpath + "/remove1.revision_tree.json"
), o.doctree, "Check document tree");
// 6. check if the attachment still exists
deepEqual(util.jsonlocalstorage.getItem(
o.localpath + "/remove1.2-oldrev/remove2"
), "abc", "Check attachment -> still exists");
// 7. check if document is updated
deepEqual(util.jsonlocalstorage.getItem(
o.localpath + "/remove1.3-" + o.rev_hash
), {
"_id": "remove1.3-" + o.rev_hash,
"title": "myRemove1",
"_attachments": {"remove3": o.attachment_remove3}
}, "Check document");
// 8. remove document with wrong revision
o.spy(o, "status", 409, "Remove document with wrong revision " +
"-> 409 Conflict");
o.jio.remove({"_id": "remove1", "_rev": "1-a"}, o.f);
o.tick(o);
// 9. remove attachment wrong revision
o.spy(o, "status", 409, "Remove attachment with wrong revision " +
"-> 409 Conflict");
o.jio.removeAttachment({
"_id": "remove1",
"_attachment": "remove2",
"_rev": "1-a"
}, o.f);
o.tick(o);
// 10. remove document
o.last_rev = "3-" + o.rev_hash;
o.rev_hash = generateRevisionHash(
{"_id": "remove1"},
{"start": 3, "ids": [o.rev_hash, "oldrev", "veryoldrev"]},
true
);
o.spy(o, "value", {"ok": true, "id": "remove1", "rev": "4-" + o.rev_hash},
"Remove document");
o.jio.remove({"_id": "remove1", "_rev": o.last_rev}, o.f);
o.tick(o);
// 11. check document tree
o.doctree.children[0].children[0].children[0].children.unshift({
"rev": "4-" + o.rev_hash,
"status": "deleted",
"children": []
});
deepEqual(util.jsonlocalstorage.getItem(
o.localpath + "/remove1.revision_tree.json"
), o.doctree, "Check document tree");
return jio_local.get({"_id": "post1.revision_tree.json"});
util.closeAndcleanUpJio(o.jio);
});
}).then(function (answer) {
test("allDocs", function () {
deepEqual(answer.data, shared.doc_tree, "Check document tree");
var o = generateTools();
}).fail(unexpectedError).always(start);
o.jio = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "urevad1",
"application_name": "arevad1"
}
});
o.localpath = "jio/localstorage/urevad1/arevad1";
// adding 3 documents
o.jio.put({"_id": "yes"}, function (err, response) {
o.rev1 = (response || {}).rev;
});
o.jio.put({"_id": "no"}, function (err, response) {
o.rev2 = (response || {}).rev;
});
o.jio.put({"_id": "maybe"}, function (err, response) {
o.rev3 = (response || {}).rev;
});
o.clock.tick(1000);
// adding conflicts
o.jio.put({"_id": "maybe"});
// adding 2 attachments
o.jio.putAttachment({
"_id": "yes",
"_attachment": "blue",
"_mimetype": "text/plain",
"_rev": o.rev1,
"_data": "sky"
}, function (err, response) {
o.rev1 = (response || {}).rev;
});
o.jio.putAttachment({
"_id": "no",
"_attachment": "Heeeee!",
"_mimetype": "text/plain",
"_rev": o.rev2,
"_data": "Hooooo!"
}, function (err, response) {
o.rev2 = (response || {}).rev;
});
o.clock.tick(1000);
o.rows = {
"total_rows": 3,
"rows": [{
"id": "maybe",
"key": "maybe",
"value": {
"rev": o.rev3
}
}, {
"id": "no",
"key": "no",
"value": {
"rev": o.rev2
}
}, {
"id": "yes",
"key": "yes",
"value": {
"rev": o.rev1
}
}]
};
o.spy(o, "value", o.rows, "allDocs");
o.jio.allDocs(function (err, response) {
if (response && response.rows) {
response.rows.sort(function (a, b) {
return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
});
}
o.f(err, response);
});
o.tick(o);
o.rows.rows[0].doc = {
"_id": "maybe",
"_rev": o.rev3
};
o.rows.rows[1].doc = {
"_id": "no",
"_rev": o.rev2,
"_attachments": {
"Heeeee!": {
"content_type": "text/plain",
"digest": "md5-2686969b0bc0fd9bc186146a1ecb09a7",
"length": 7
}
},
};
o.rows.rows[2].doc = {
"_id": "yes",
"_rev": o.rev1,
"_attachments": {
"blue": {
"content_type": "text/plain",
"digest": "md5-900bc885d7553375aec470198a9514f3",
"length": 3
}
},
};
o.spy(o, "value", o.rows, "allDocs + include docs");
o.jio.allDocs({"include_docs": true}, function (err, response) {
if (response && response.rows) {
response.rows.sort(function (a, b) {
return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
});
}
o.f(err, response);
});
o.tick(o);
util.closeAndcleanUpJio(o.jio);
});
test("Scenario", function () {
var o = generateTools();
o.jio = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "usam1",
"application_name": "asam1"
}
});
o.localpath = "jio/localstorage/usam1/asam1";
// new application
ok(o.jio, "I open my application with revision and localstorage");
// put non empty document A-1
o.doc = {"_id": "sample1", "title": "mySample1"};
o.revisions = {"start": 0, "ids": []};
o.hex = generateRevisionHash(o.doc, o.revisions);
o.rev = "1-" + o.hex;
o.spy(o, "value", {"ok": true, "id": "sample1", "rev": o.rev},
"Then, I create a new document (no attachment), my application " +
"keep the revision in memory");
o.jio.put(o.doc, o.f);
o.tick(o);
// open new tab (JIO)
o.jio2 = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "usam1",
"application_name": "asam1"
}
});
o.localpath = "jio/localstorage/usam1/asam1";
// Create a new JIO in a new tab
ok(o.jio2, "Now, I am opening a new tab, with the same application" +
" and the same storage tree");
// Get the document from the first storage
o.doc._rev = o.rev;
o.doc._revisions = {"ids": [o.hex], "start": 1};
o.doc._revs_info = [{"rev": o.rev, "status": "available"}];
o.spy(o, "value", o.doc, "And, on this new tab, I load the document," +
"and my application keep the revision in memory");
o.jio2.get({"_id": "sample1", "_rev": o.rev}, {
"revs_info": true,
"revs": true,
"conflicts": true,
}, o.f);
o.tick(o);
// MODIFY the 2nd version
o.doc_2 = {"_id": "sample1", "_rev": o.rev,
"title": "mySample2_modified"};
o.revisions_2 = {"start": 1, "ids": [o.hex]};
o.hex_2 = generateRevisionHash(o.doc_2, o.revisions_2);
o.rev_2 = "2-" + o.hex_2;
o.spy(o, "value", {"id": "sample1", "ok": true, "rev": o.rev_2},
"So, I can modify and update it");
o.jio2.put(o.doc_2, o.f);
o.tick(o);
// MODIFY first version
o.doc_1 = {
"_id": "sample1",
"_rev": o.rev,
"title": "mySample1_modified"
};
o.revisions_1 = {"start": 1, "ids": [o.rev.split('-')[1]]};
o.hex_1 = generateRevisionHash(o.doc_1, o.revisions_1);
o.rev_1 = "2-" + o.hex_1;
o.spy(o, "value", {"id": "sample1", "ok": true, "rev": o.rev_1},
"Back to the first tab, I update the document.");
o.jio.put(o.doc_1, o.f);
o.tick(o);
// Close 1st tab
o.jio.close();
// Close 2nd tab
o.jio2.close();
ok(o.jio2, "I close tab both tabs");
// Reopen JIO
o.jio = jIO.newJio({
"type": "revision",
"sub_storage": {
"type": "local",
"username": "usam1",
"application_name": "asam1"
}
});
o.localpath = "jio/localstorage/usam1/asam1";
ok(o.jio, "Later, I open my application again");
// GET document without revision = winner & conflict!
o.mydocSample3 = {"_id": "sample1", "title": "mySample1_modified",
"_rev": o.rev_1};
o.mydocSample3._conflicts = [o.rev_2];
o.mydocSample3._revs_info = [{"rev": o.rev_1, "status": "available"}, {
"rev": o.rev,
"status": "available"
}];
o.mydocSample3._revisions = {"ids": [o.hex_1, o.hex], "start": 2};
o.spy(o, "value", o.mydocSample3, "I load the same document as before" +
", and a popup shows that there is a conflict");
o.jio.get({"_id": "sample1"}, {
"revs_info": true,
"revs": true,
"conflicts": true
}, o.f);
o.tick(o);
// REMOVE one of the two conflicting versions
o.revisions = {"start": 2, "ids": [
o.rev_1.split('-')[1],
o.rev.split('-')[1]
]};
o.doc_myremove3 = {"_id": "sample1", "_rev": o.rev_1};
o.rev_3 = "3-" + generateRevisionHash(o.doc_myremove3, o.revisions, true);
o.spy(o, "value", {"ok": true, "id": "sample1", "rev": o.rev_3},
"I choose one of the document and close the application.");
o.jio.remove({"_id": "sample1", "_rev": o.rev_1}, o.f);
o.tick(o);
// check to see if conflict still exists
o.mydocSample4 = {
"_id": "sample1",
"title": "mySample2_modified",
"_rev": o.rev_2
};
o.mydocSample4._revs_info = [{"rev": o.rev_2, "status": "available"}, {
"rev": o.rev,
"status": "available"
}];
o.mydocSample4._revisions = {"ids": [o.hex_2, o.hex], "start": 2};
o.spy(o, "value", o.mydocSample4, "Test if conflict still exists");
o.jio.get({"_id": "sample1"}, {
"revs_info": true,
"revs": true,
"conflicts": true
}, o.f);
o.tick(o);
// END
util.closeAndcleanUpJio(o.jio);
});
// test("Put", function () {
// var o = generateTools();
// o.jio = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "urevput",
// "application_name": "arevput"
// }
// });
// o.localpath = "jio/localstorage/urevput/arevput";
// // put without id
// // error 20 -> document id required
// o.spy(o, "status", 20, "Put without id");
// o.jio.put({}, o.f);
// o.tick(o);
// // put non empty document
// o.doc = {"_id": "put1", "title": "myPut1"};
// o.revisions = {"start": 0, "ids": []};
// o.rev = "1-" + generateRevisionHash(o.doc, o.revisions);
// o.spy(o, "value", {"ok": true, "id": "put1", "rev": o.rev},
// "Creates a document");
// o.jio.put(o.doc, o.f);
// o.tick(o);
// // check document
// o.doc._id = "put1." + o.rev;
// deepEqual(
// util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
// o.doc,
// "Check document"
// );
// // check document tree
// o.doc_tree = {
// "_id": "put1.revision_tree.json",
// "children": [{
// "rev": o.rev,
// "status": "available",
// "children": []
// }]
// };
// deepEqual(
// util.jsonlocalstorage.getItem(
// o.localpath + "/put1.revision_tree.json"
// ),
// o.doc_tree,
// "Check document tree"
// );
// // put without rev and document already exists
// o.doc = {"_id": "put1", "title": "myPut2"};
// o.rev = "1-" + generateRevisionHash(o.doc, o.revisions);
// o.spy(o, "value", {"ok": true, "id": "put1", "rev": o.rev},
// "Put same document without revision");
// o.jio.put(o.doc, o.f);
// o.tick(o);
// o.doc_tree.children.unshift({
// "rev": o.rev,
// "status": "available",
// "children": []
// });
// // put + revision
// o.doc = {"_id": "put1", "_rev": o.rev, "title": "myPut2"};
// o.revisions = {"start": 1, "ids": [o.rev.split('-')[1]]};
// o.rev = "2-" + generateRevisionHash(o.doc, o.revisions);
// o.spy(o, "value", {"id": "put1", "ok": true, "rev": o.rev},
// "Put + revision");
// o.jio.put(o.doc, o.f);
// o.tick(o);
// // check document
// o.doc._id = "put1." + o.rev;
// delete o.doc._rev;
// deepEqual(
// util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
// o.doc,
// "Check document"
// );
// // check document tree
// o.doc_tree.children[0].children.unshift({
// "rev": o.rev,
// "status": "available",
// "children": []
// });
// deepEqual(
// util.jsonlocalstorage.getItem(
// o.localpath + "/put1.revision_tree.json"
// ),
// o.doc_tree,
// "Check document tree"
// );
// // put + wrong revision
// o.doc = {"_id": "put1", "_rev": "3-wr3", "title": "myPut3"};
// o.revisions = {"start": 3, "ids": ["wr3"]};
// o.rev = "4-" + generateRevisionHash(o.doc, o.revisions);
// o.spy(o, "value", {"id": "put1", "ok": true, "rev": o.rev},
// "Put + wrong revision");
// o.jio.put(o.doc, o.f);
// o.tick(o);
// // check document
// o.doc._id = "put1." + o.rev;
// delete o.doc._rev;
// deepEqual(
// util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
// o.doc,
// "Check document"
// );
// // check document tree
// o.doc_tree.children.unshift({
// "rev": "3-wr3",
// "status": "missing",
// "children": [{
// "rev": o.rev,
// "status": "available",
// "children": []
// }]
// });
// deepEqual(
// util.jsonlocalstorage.getItem(
// o.localpath + "/put1.revision_tree.json"
// ),
// o.doc_tree,
// "Check document tree"
// );
// // put + revision history
// o.doc = {
// "_id": "put1",
// //"_revs": ["3-rh3", "2-rh2", "1-rh1"], // same as below
// "_revs": {"start": 3, "ids": ["rh3", "rh2", "rh1"]},
// "title": "myPut3"
// };
// o.spy(o, "value", {"id": "put1", "ok": true, "rev": "3-rh3"},
// "Put + revision history");
// o.jio.put(o.doc, o.f);
// o.tick(o);
// // check document
// o.doc._id = "put1.3-rh3";
// delete o.doc._revs;
// deepEqual(
// util.jsonlocalstorage.getItem(o.localpath + "/put1.3-rh3"),
// o.doc,
// "Check document"
// );
// // check document tree
// o.doc_tree.children.unshift({
// "rev": "1-rh1",
// "status": "missing",
// "children": [{
// "rev": "2-rh2",
// "status": "missing",
// "children": [{
// "rev": "3-rh3",
// "status": "available",
// "children": []
// }]
// }]
// });
// deepEqual(
// util.jsonlocalstorage.getItem(
// o.localpath + "/put1.revision_tree.json"
// ),
// o.doc_tree,
// "Check document tree"
// );
// // add attachment
// o.doc._attachments = {
// "att1": {
// "length": 1,
// "content_type": "text/plain",
// "digest": "md5-0cc175b9c0f1b6a831c399e269772661"
// },
// "att2": {
// "length": 2,
// "content_type": "dont/care",
// "digest": "md5-5360af35bde9ebd8f01f492dc059593c"
// }
// };
// util.jsonlocalstorage.setItem(o.localpath + "/put1.3-rh3", o.doc);
// util.jsonlocalstorage.setItem(o.localpath + "/put1.3-rh3/att1", "a");
// util.jsonlocalstorage.setItem(o.localpath + "/put1.3-rh3/att2", "bc");
// // put + revision with attachment
// o.attachments = o.doc._attachments;
// o.doc = {"_id": "put1", "_rev": "3-rh3", "title": "myPut4"};
// o.revisions = {"start": 3, "ids": ["rh3", "rh2", "rh1"]};
// o.rev = "4-" + generateRevisionHash(o.doc, o.revisions);
// o.spy(o, "value", {"id": "put1", "ok": true, "rev": o.rev},
// "Put + revision (document contains attachments)");
// o.jio.put(o.doc, o.f);
// o.tick(o);
// // check document
// o.doc._id = "put1." + o.rev;
// o.doc._attachments = o.attachments;
// delete o.doc._rev;
// deepEqual(
// util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev),
// o.doc,
// "Check document"
// );
// // check attachments
// deepEqual(
// util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev + "/att1"),
// "a",
// "Check Attachment"
// );
// deepEqual(
// util.jsonlocalstorage.getItem(o.localpath + "/put1." + o.rev + "/att2"),
// "bc",
// "Check Attachment"
// );
// // check document tree
// o.doc_tree.children[0].children[0].children[0].children.unshift({
// "rev": o.rev,
// "status": "available",
// "children": []
// });
// deepEqual(
// util.jsonlocalstorage.getItem(
// o.localpath + "/put1.revision_tree.json"
// ),
// o.doc_tree,
// "Check document tree"
// );
// util.closeAndcleanUpJio(o.jio);
// });
// test("Put Attachment", function () {
// var o = generateTools();
// o.jio = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "urevputattmt",
// "application_name": "arevputattmt"
// }
// });
// // putAttachment without doc id
// // error 20 -> document id required
// o.spy(o, "status", 20, "PutAttachment without doc id" +
// " -> 20 document id required");
// o.jio.putAttachment({}, o.f);
// o.tick(o);
// // putAttachment without attachment id
// // erorr 22 -> attachment id required
// o.spy(o, "status", 22, "PutAttachment without attachment id" +
// " -> 22 attachment id required");
// o.jio.putAttachment({"_id": "putattmt1"}, o.f);
// o.tick(o);
// // putAttachment without document
// o.revisions = {"start": 0, "ids": []};
// o.rev_hash = generateRevisionHash({"_id": "doc1", "_attachment": "attmt1"},
// o.revisions);
// o.rev = "1-" + o.rev_hash;
// o.spy(o, "value",
// {"ok": true, "id": "doc1", "attachment": "attmt1", "rev": o.rev},
// "PutAttachment without document, without data");
// o.jio.putAttachment({"_id": "doc1", "_attachment": "attmt1"}, o.f);
// o.tick(o);
// // check document
// deepEqual(
// util.jsonlocalstorage.getItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
// ),
// {
// "_id": "doc1." + o.rev,
// "_attachments": {
// "attmt1": {
// "length": 0,
// // md5("")
// "digest": "md5-d41d8cd98f00b204e9800998ecf8427e"
// }
// }
// },
// "Check document"
// );
// // check attachment
// deepEqual(util.jsonlocalstorage.getItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
// + "/attmt1"
// ), "", "Check attachment");
// // adding a metadata to the document
// o.doc = util.jsonlocalstorage.getItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
// );
// o.doc.title = "My Title";
// util.jsonlocalstorage.setItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev,
// o.doc
// );
// // update attachment
// o.prev_rev = o.rev;
// o.revisions = {"start": 1, "ids": [o.rev_hash]};
// o.rev_hash = generateRevisionHash({
// "_id": "doc1",
// "_data": "abc",
// "_attachment": "attmt1",
// }, o.revisions);
// o.rev = "2-" + o.rev_hash;
// o.spy(o, "value",
// {"ok": true, "id": "doc1", "attachment": "attmt1", "rev": o.rev},
// "Update Attachment, with data");
// o.jio.putAttachment({
// "_id": "doc1",
// "_data": "abc",
// "_attachment": "attmt1",
// "_rev": o.prev_rev
// }, o.f);
// o.tick(o);
// // check document
// deepEqual(
// util.jsonlocalstorage.getItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
// ),
// {
// "_id": "doc1." + o.rev,
// "title": "My Title",
// "_attachments": {
// "attmt1": {
// "length": 3,
// // md5("abc")
// "digest": "md5-900150983cd24fb0d6963f7d28e17f72"
// }
// }
// },
// "Check document"
// );
// // check attachment
// deepEqual(util.jsonlocalstorage.getItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev +
// "/attmt1"
// ), "abc", "Check attachment");
// // putAttachment new attachment
// o.prev_rev = o.rev;
// o.revisions = {"start": 2, "ids": [o.rev_hash, o.revisions.ids[0]]};
// o.rev_hash = generateRevisionHash({
// "_id": "doc1",
// "_data": "def",
// "_attachment": "attmt2",
// }, o.revisions);
// o.rev = "3-" + o.rev_hash;
// o.spy(o, "value",
// {"ok": true, "id": "doc1", "attachment": "attmt2", "rev": o.rev},
// "PutAttachment without document, without data");
// o.jio.putAttachment({
// "_id": "doc1",
// "_data": "def",
// "_attachment": "attmt2",
// "_rev": o.prev_rev
// }, o.f);
// o.tick(o);
// // check document
// deepEqual(
// util.jsonlocalstorage.getItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev
// ),
// {
// "_id": "doc1." + o.rev,
// "title": "My Title",
// "_attachments": {
// "attmt1": {
// "length": 3,
// "digest": "md5-900150983cd24fb0d6963f7d28e17f72"
// },
// "attmt2": {
// "length": 3,
// // md5("def")
// "digest": "md5-4ed9407630eb1000c0f6b63842defa7d"
// }
// }
// },
// "Check document"
// );
// // check attachment
// deepEqual(util.jsonlocalstorage.getItem(
// "jio/localstorage/urevputattmt/arevputattmt/doc1." + o.rev +
// "/attmt2"
// ), "def", "Check attachment");
// util.closeAndcleanUpJio(o.jio);
// });
// test("Get", function () {
// var o = generateTools();
// o.jio = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "urevget",
// "application_name": "arevget"
// }
// });
// o.localpath = "jio/localstorage/urevget/arevget";
// // get inexistent document
// o.spy(o, "status", 404, "Get inexistent document (winner)" +
// " -> 404 Not Found");
// o.jio.get({"_id": "get1"}, o.f);
// o.tick(o);
// // get inexistent attachment
// o.spy(o, "status", 404, "Get inexistent attachment (winner)" +
// " -> 404 Not Found");
// o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
// o.tick(o);
// // adding a document
// o.doctree = {"children": [{
// "rev": "1-rev1",
// "status": "available",
// "children": []
// }]};
// o.doc_myget1 = {"_id": "get1.1-rev1", "title": "myGet1"};
// util.jsonlocalstorage.setItem(
// o.localpath + "/get1.revision_tree.json",
// o.doctree
// );
// util.jsonlocalstorage.setItem(o.localpath + "/get1.1-rev1", o.doc_myget1);
// // get document
// o.doc_myget1_cloned = deepClone(o.doc_myget1);
// o.doc_myget1_cloned._id = "get1";
// o.doc_myget1_cloned._rev = "1-rev1";
// o.doc_myget1_cloned._revisions = {"start": 1, "ids": ["rev1"]};
// o.doc_myget1_cloned._revs_info = [{
// "rev": "1-rev1",
// "status": "available"
// }];
// o.spy(o, "value", o.doc_myget1_cloned, "Get document (winner)");
// o.jio.get({"_id": "get1"}, {
// "revs_info": true,
// "revs": true,
// "conflicts": true
// }, o.f);
// o.tick(o);
// // adding two documents
// o.doctree = {"children": [{
// "rev": "1-rev1",
// "status": "available",
// "children": []
// }, {
// "rev": "1-rev2",
// "status": "available",
// "children": [{
// "rev": "2-rev3",
// "status": "available",
// "children": []
// }]
// }]};
// o.doc_myget2 = {"_id": "get1.1-rev2", "title": "myGet2"};
// o.doc_myget3 = {"_id": "get1.2-rev3", "title": "myGet3"};
// util.jsonlocalstorage.setItem(
// o.localpath + "/get1.revision_tree.json",
// o.doctree
// );
// util.jsonlocalstorage.setItem(o.localpath + "/get1.1-rev2", o.doc_myget2);
// util.jsonlocalstorage.setItem(o.localpath + "/get1.2-rev3", o.doc_myget3);
// // get document
// o.doc_myget3_cloned = deepClone(o.doc_myget3);
// o.doc_myget3_cloned._id = "get1";
// o.doc_myget3_cloned._rev = "2-rev3";
// o.doc_myget3_cloned._revisions = {"start": 2, "ids": ["rev3", "rev2"]};
// o.doc_myget3_cloned._revs_info = [{
// "rev": "2-rev3",
// "status": "available"
// }, {
// "rev": "1-rev2",
// "status": "available"
// }];
// o.doc_myget3_cloned._conflicts = ["1-rev1"];
// o.spy(o, "value", o.doc_myget3_cloned,
// "Get document (winner, after posting another one)");
// o.jio.get({"_id": "get1"},
// {"revs_info": true, "revs": true, "conflicts": true},
// o.f);
// o.tick(o);
// // get inexistent specific document
// o.spy(o, "status", 404, "Get document (inexistent specific revision)" +
// " -> 404 Not Found");
// o.jio.get({"_id": "get1", "_rev": "1-rev0"}, {
// "revs_info": true,
// "revs": true,
// "conflicts": true,
// }, o.f);
// o.tick(o);
// // get specific document
// o.doc_myget2_cloned = deepClone(o.doc_myget2);
// o.doc_myget2_cloned._id = "get1";
// o.doc_myget2_cloned._rev = "1-rev2";
// o.doc_myget2_cloned._revisions = {"start": 1, "ids": ["rev2"]};
// o.doc_myget2_cloned._revs_info = [{
// "rev": "1-rev2",
// "status": "available"
// }];
// o.doc_myget2_cloned._conflicts = ["1-rev1"];
// o.spy(o, "value", o.doc_myget2_cloned, "Get document (specific revision)");
// o.jio.get({"_id": "get1", "_rev": "1-rev2"}, {
// "revs_info": true,
// "revs": true,
// "conflicts": true,
// }, o.f);
// o.tick(o);
// // adding an attachment
// o.attmt_myget3 = {
// "get2": {
// "length": 3,
// "digest": "md5-dontcare",
// "content_type": "oh/yeah"
// }
// };
// o.doc_myget3._attachments = o.attmt_myget3;
// util.jsonlocalstorage.setItem(o.localpath + "/get1.2-rev3", o.doc_myget3);
// util.jsonlocalstorage.setItem(o.localpath + "/get1.2-rev3/get2", "abc");
// // get attachment winner
// o.spy(o, "value", "abc", "Get attachment (winner)");
// o.jio.getAttachment({"_id": "get1", "_attachment": "get2"}, o.f);
// o.tick(o);
// // get inexistent attachment specific rev
// o.spy(o, "status", 404, "Get inexistent attachment (specific revision)" +
// " -> 404 Not Found");
// o.jio.getAttachment({
// "_id": "get1",
// "_attachment": "get2",
// "_rev": "1-rev1"
// }, {
// "revs_info": true,
// "revs": true,
// "conflicts": true,
// }, o.f);
// o.tick(o);
// // get attachment specific rev
// o.spy(o, "value", "abc", "Get attachment (specific revision)");
// o.jio.getAttachment({
// "_id": "get1",
// "_attachment": "get2",
// "_rev": "2-rev3"
// }, {
// "revs_info": true,
// "revs": true,
// "conflicts": true,
// }, o.f);
// o.tick(o);
// // get document with attachment (specific revision)
// delete o.doc_myget2_cloned._attachments;
// o.spy(o, "value", o.doc_myget2_cloned,
// "Get document which have an attachment (specific revision)");
// o.jio.get({"_id": "get1", "_rev": "1-rev2"}, {
// "revs_info": true,
// "revs": true,
// "conflicts": true
// }, o.f);
// o.tick(o);
// // get document with attachment (winner)
// o.doc_myget3_cloned._attachments = o.attmt_myget3;
// o.spy(o, "value", o.doc_myget3_cloned,
// "Get document which have an attachment (winner)");
// o.jio.get({"_id": "get1"},
// {"revs_info": true, "revs": true, "conflicts": true},
// o.f);
// o.tick(o);
// util.closeAndcleanUpJio(o.jio);
// });
// test("Remove", function () {
// var o = generateTools();
// o.jio = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "urevrem",
// "application_name": "arevrem"
// }
// });
// o.localpath = "jio/localstorage/urevrem/arevrem";
// // 1. remove document without revision
// o.spy(o, "status", 409, "Remove document without revision " +
// "-> 409 Conflict");
// o.jio.remove({"_id": "remove1"}, o.f);
// o.tick(o);
// // 2. remove attachment without revision
// o.spy(o, "status", 409, "Remove attachment without revision " +
// "-> 409 Conflict");
// o.jio.removeAttachment({"_id": "remove1", "_attachment": "remove2"}, o.f);
// o.tick(o);
// // adding a document with attachments
// o.doc_myremove1 = {
// "_id": "remove1.1-veryoldrev",
// "title": "myRemove1"
// };
// util.jsonlocalstorage.setItem(o.localpath + "/remove1.1-veryoldrev",
// o.doc_myremove1);
// o.doc_myremove1._id = "remove1.2-oldrev";
// o.attachment_remove2 = {
// "length": 3,
// "digest": "md5-dontcare",
// "content_type": "oh/yeah"
// };
// o.attachment_remove3 = {
// "length": 5,
// "digest": "md5-865f5cc7fbd7854902eae9d8211f178a",
// "content_type": "he/ho"
// };
// o.doc_myremove1._attachments = {
// "remove2": o.attachment_remove2,
// "remove3": o.attachment_remove3
// };
// util.jsonlocalstorage.setItem(o.localpath + "/remove1.2-oldrev",
// o.doc_myremove1);
// util.jsonlocalstorage.setItem(
// o.localpath + "/remove1.2-oldrev/remove2",
// "abc"
// );
// util.jsonlocalstorage.setItem(
// o.localpath + "/remove1.2-oldrev/remove3",
// "defgh"
// );
// // add document tree
// o.doctree = {
// "children": [{
// "rev": "1-veryoldrev",
// "status": "available",
// "children": [{
// "rev": "2-oldrev",
// "status": "available",
// "children": []
// }]
// }]
// };
// util.jsonlocalstorage.setItem(o.localpath + "/remove1.revision_tree.json",
// o.doctree);
// // 3. remove inexistent attachment
// o.spy(o, "status", 404, "Remove inexistent attachment -> 404 Not Found");
// o.jio.removeAttachment({
// "_id": "remove1",
// "_attachment": "remove0",
// "_rev": "2-oldrev"
// }, o.f);
// o.tick(o);
// // 4. remove existing attachment
// o.rev_hash = generateRevisionHash({
// "_id": "remove1",
// "_attachment": "remove2",
// }, {"start": 2, "ids": ["oldrev", "veryoldrev"]});
// o.spy(o, "value", {
// "ok": true,
// "id": "remove1",
// "attachment": "remove2",
// "rev": "3-" + o.rev_hash
// }, "Remove existing attachment");
// o.jio.removeAttachment({
// "_id": "remove1",
// "_attachment": "remove2",
// "_rev": "2-oldrev"
// }, o.f);
// o.tick(o);
// o.doctree = {
// "_id": "remove1.revision_tree.json",
// "children": [{
// "rev": "1-veryoldrev",
// "status": "available",
// "children": [{
// "rev": "2-oldrev",
// "status": "available",
// "children": [{
// "rev": "3-" + o.rev_hash,
// "status": "available",
// "children": []
// }]
// }]
// }]
// };
// // 5. check if document tree has been updated correctly
// deepEqual(util.jsonlocalstorage.getItem(
// o.localpath + "/remove1.revision_tree.json"
// ), o.doctree, "Check document tree");
// // 6. check if the attachment still exists
// deepEqual(util.jsonlocalstorage.getItem(
// o.localpath + "/remove1.2-oldrev/remove2"
// ), "abc", "Check attachment -> still exists");
// // 7. check if document is updated
// deepEqual(util.jsonlocalstorage.getItem(
// o.localpath + "/remove1.3-" + o.rev_hash
// ), {
// "_id": "remove1.3-" + o.rev_hash,
// "title": "myRemove1",
// "_attachments": {"remove3": o.attachment_remove3}
// }, "Check document");
// // 8. remove document with wrong revision
// o.spy(o, "status", 409, "Remove document with wrong revision " +
// "-> 409 Conflict");
// o.jio.remove({"_id": "remove1", "_rev": "1-a"}, o.f);
// o.tick(o);
// // 9. remove attachment wrong revision
// o.spy(o, "status", 409, "Remove attachment with wrong revision " +
// "-> 409 Conflict");
// o.jio.removeAttachment({
// "_id": "remove1",
// "_attachment": "remove2",
// "_rev": "1-a"
// }, o.f);
// o.tick(o);
// // 10. remove document
// o.last_rev = "3-" + o.rev_hash;
// o.rev_hash = generateRevisionHash(
// {"_id": "remove1"},
// {"start": 3, "ids": [o.rev_hash, "oldrev", "veryoldrev"]},
// true
// );
// o.spy(o, "value", {"ok": true, "id": "remove1", "rev": "4-" + o.rev_hash},
// "Remove document");
// o.jio.remove({"_id": "remove1", "_rev": o.last_rev}, o.f);
// o.tick(o);
// // 11. check document tree
// o.doctree.children[0].children[0].children[0].children.unshift({
// "rev": "4-" + o.rev_hash,
// "status": "deleted",
// "children": []
// });
// deepEqual(util.jsonlocalstorage.getItem(
// o.localpath + "/remove1.revision_tree.json"
// ), o.doctree, "Check document tree");
// util.closeAndcleanUpJio(o.jio);
// });
// test("allDocs", function () {
// var o = generateTools();
// o.jio = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "urevad1",
// "application_name": "arevad1"
// }
// });
// o.localpath = "jio/localstorage/urevad1/arevad1";
// // adding 3 documents
// o.jio.put({"_id": "yes"}, function (err, response) {
// o.rev1 = (response || {}).rev;
// });
// o.jio.put({"_id": "no"}, function (err, response) {
// o.rev2 = (response || {}).rev;
// });
// o.jio.put({"_id": "maybe"}, function (err, response) {
// o.rev3 = (response || {}).rev;
// });
// o.clock.tick(1000);
// // adding conflicts
// o.jio.put({"_id": "maybe"});
// // adding 2 attachments
// o.jio.putAttachment({
// "_id": "yes",
// "_attachment": "blue",
// "_mimetype": "text/plain",
// "_rev": o.rev1,
// "_data": "sky"
// }, function (err, response) {
// o.rev1 = (response || {}).rev;
// });
// o.jio.putAttachment({
// "_id": "no",
// "_attachment": "Heeeee!",
// "_mimetype": "text/plain",
// "_rev": o.rev2,
// "_data": "Hooooo!"
// }, function (err, response) {
// o.rev2 = (response || {}).rev;
// });
// o.clock.tick(1000);
// o.rows = {
// "total_rows": 3,
// "rows": [{
// "id": "maybe",
// "key": "maybe",
// "value": {
// "rev": o.rev3
// }
// }, {
// "id": "no",
// "key": "no",
// "value": {
// "rev": o.rev2
// }
// }, {
// "id": "yes",
// "key": "yes",
// "value": {
// "rev": o.rev1
// }
// }]
// };
// o.spy(o, "value", o.rows, "allDocs");
// o.jio.allDocs(function (err, response) {
// if (response && response.rows) {
// response.rows.sort(function (a, b) {
// return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
// });
// }
// o.f(err, response);
// });
// o.tick(o);
// o.rows.rows[0].doc = {
// "_id": "maybe",
// "_rev": o.rev3
// };
// o.rows.rows[1].doc = {
// "_id": "no",
// "_rev": o.rev2,
// "_attachments": {
// "Heeeee!": {
// "content_type": "text/plain",
// "digest": "md5-2686969b0bc0fd9bc186146a1ecb09a7",
// "length": 7
// }
// },
// };
// o.rows.rows[2].doc = {
// "_id": "yes",
// "_rev": o.rev1,
// "_attachments": {
// "blue": {
// "content_type": "text/plain",
// "digest": "md5-900bc885d7553375aec470198a9514f3",
// "length": 3
// }
// },
// };
// o.spy(o, "value", o.rows, "allDocs + include docs");
// o.jio.allDocs({"include_docs": true}, function (err, response) {
// if (response && response.rows) {
// response.rows.sort(function (a, b) {
// return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
// });
// }
// o.f(err, response);
// });
// o.tick(o);
// util.closeAndcleanUpJio(o.jio);
// });
// test("Scenario", function () {
// var o = generateTools();
// o.jio = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "usam1",
// "application_name": "asam1"
// }
// });
// o.localpath = "jio/localstorage/usam1/asam1";
// // new application
// ok(o.jio, "I open my application with revision and localstorage");
// // put non empty document A-1
// o.doc = {"_id": "sample1", "title": "mySample1"};
// o.revisions = {"start": 0, "ids": []};
// o.hex = generateRevisionHash(o.doc, o.revisions);
// o.rev = "1-" + o.hex;
// o.spy(o, "value", {"ok": true, "id": "sample1", "rev": o.rev},
// "Then, I create a new document (no attachment), my application " +
// "keep the revision in memory");
// o.jio.put(o.doc, o.f);
// o.tick(o);
// // open new tab (JIO)
// o.jio2 = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "usam1",
// "application_name": "asam1"
// }
// });
// o.localpath = "jio/localstorage/usam1/asam1";
// // Create a new JIO in a new tab
// ok(o.jio2, "Now, I am opening a new tab, with the same application" +
// " and the same storage tree");
// // Get the document from the first storage
// o.doc._rev = o.rev;
// o.doc._revisions = {"ids": [o.hex], "start": 1};
// o.doc._revs_info = [{"rev": o.rev, "status": "available"}];
// o.spy(o, "value", o.doc, "And, on this new tab, I load the document," +
// "and my application keep the revision in memory");
// o.jio2.get({"_id": "sample1", "_rev": o.rev}, {
// "revs_info": true,
// "revs": true,
// "conflicts": true,
// }, o.f);
// o.tick(o);
// // MODIFY the 2nd version
// o.doc_2 = {"_id": "sample1", "_rev": o.rev,
// "title": "mySample2_modified"};
// o.revisions_2 = {"start": 1, "ids": [o.hex]};
// o.hex_2 = generateRevisionHash(o.doc_2, o.revisions_2);
// o.rev_2 = "2-" + o.hex_2;
// o.spy(o, "value", {"id": "sample1", "ok": true, "rev": o.rev_2},
// "So, I can modify and update it");
// o.jio2.put(o.doc_2, o.f);
// o.tick(o);
// // MODIFY first version
// o.doc_1 = {
// "_id": "sample1",
// "_rev": o.rev,
// "title": "mySample1_modified"
// };
// o.revisions_1 = {"start": 1, "ids": [o.rev.split('-')[1]]};
// o.hex_1 = generateRevisionHash(o.doc_1, o.revisions_1);
// o.rev_1 = "2-" + o.hex_1;
// o.spy(o, "value", {"id": "sample1", "ok": true, "rev": o.rev_1},
// "Back to the first tab, I update the document.");
// o.jio.put(o.doc_1, o.f);
// o.tick(o);
// // Close 1st tab
// o.jio.close();
// // Close 2nd tab
// o.jio2.close();
// ok(o.jio2, "I close tab both tabs");
// // Reopen JIO
// o.jio = jIO.newJio({
// "type": "revision",
// "sub_storage": {
// "type": "local",
// "username": "usam1",
// "application_name": "asam1"
// }
// });
// o.localpath = "jio/localstorage/usam1/asam1";
// ok(o.jio, "Later, I open my application again");
// // GET document without revision = winner & conflict!
// o.mydocSample3 = {"_id": "sample1", "title": "mySample1_modified",
// "_rev": o.rev_1};
// o.mydocSample3._conflicts = [o.rev_2];
// o.mydocSample3._revs_info = [{"rev": o.rev_1, "status": "available"}, {
// "rev": o.rev,
// "status": "available"
// }];
// o.mydocSample3._revisions = {"ids": [o.hex_1, o.hex], "start": 2};
// o.spy(o, "value", o.mydocSample3, "I load the same document as before" +
// ", and a popup shows that there is a conflict");
// o.jio.get({"_id": "sample1"}, {
// "revs_info": true,
// "revs": true,
// "conflicts": true
// }, o.f);
// o.tick(o);
// // REMOVE one of the two conflicting versions
// o.revisions = {"start": 2, "ids": [
// o.rev_1.split('-')[1],
// o.rev.split('-')[1]
// ]};
// o.doc_myremove3 = {"_id": "sample1", "_rev": o.rev_1};
// o.rev_3 = "3-" + generateRevisionHash(o.doc_myremove3, o.revisions, true);
// o.spy(o, "value", {"ok": true, "id": "sample1", "rev": o.rev_3},
// "I choose one of the document and close the application.");
// o.jio.remove({"_id": "sample1", "_rev": o.rev_1}, o.f);
// o.tick(o);
// // check to see if conflict still exists
// o.mydocSample4 = {
// "_id": "sample1",
// "title": "mySample2_modified",
// "_rev": o.rev_2
// };
// o.mydocSample4._revs_info = [{"rev": o.rev_2, "status": "available"}, {
// "rev": o.rev,
// "status": "available"
// }];
// o.mydocSample4._revisions = {"ids": [o.hex_2, o.hex], "start": 2};
// o.spy(o, "value", o.mydocSample4, "Test if conflict still exists");
// o.jio.get({"_id": "sample1"}, {
// "revs_info": true,
// "revs": true,
// "conflicts": true
// }, o.f);
// o.tick(o);
// // END
// util.closeAndcleanUpJio(o.jio);
// });
}));
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