Commit 5347ff53 authored by Vincent Bechu's avatar Vincent Bechu

Revert works on saferepair and scenarii

This reverts commits
215a2cca
e391b71d
ddf61098
5d6e60dd
bafcf854
parent 642e0571
...@@ -180,8 +180,7 @@ module.exports = function (grunt) { ...@@ -180,8 +180,7 @@ module.exports = function (grunt) {
'src/jio.storage/localstorage.js', 'src/jio.storage/localstorage.js',
'src/jio.storage/indexeddbstorage.js', 'src/jio.storage/indexeddbstorage.js',
'src/jio.storage/cryptstorage.js', 'src/jio.storage/cryptstorage.js',
'src/jio.storage/websqlstorage.js', 'src/jio.storage/websqlstorage.js'
'src/jio.storage/saferepairstorage.js'
], ],
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js' dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
// dest: 'jio.js' // dest: 'jio.js'
......
/*global console, btoa, Blob, RSVP*/ /*global console, btoa, Blob*/
/*jslint nomen: true, maxlen: 200*/ /*jslint nomen: true, maxlen: 200*/
(function (window, QUnit, jIO, rJS) { (function (window, QUnit, jIO, rJS) {
"use strict"; "use strict";
...@@ -8,71 +8,225 @@ ...@@ -8,71 +8,225 @@
ok = QUnit.ok, ok = QUnit.ok,
stop = QUnit.stop, stop = QUnit.stop,
start = QUnit.start, start = QUnit.start,
module = QUnit.module, deepEqual = QUnit.deepEqual;
deepEqual = QUnit.deepEqual,
global = {defer: RSVP.defer()};
rJS(window) rJS(window)
.ready(function () { .ready(function (g) {
///////////////////////////
// Local storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// type: "document",
// document_id: "/",
// sub_storage: {
// type: "zip",
// sub_storage: {
// type: "local"
// }
// }
// }
// }
// });
///////////////////////////
// Memory storage
///////////////////////////
return g.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "union",
storage_list: [{
type: "memory"
}]
}
}
});
///////////////////////////
// WebSQL storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// "type": "websql",
// "database": "test"
// }
// }
// });
///////////////////////////
// IndexedDB storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// "type": "indexeddb",
// "database": "test"
// }
// }
// });
///////////////////////////
// DAV storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// type: "drivetojiomapping",
// sub_storage: {
// "type": "dav",
// "url": "DAVURL",
// "basic_login": btoa("LOGIN:PASSWD")
// }
// }
// }
// });
///////////////////////////
// Dropbox storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// type: "drivetojiomapping",
// sub_storage: {
// "type": "dropbox",
// "access_token" : "TOKEN",
// "root" : "dropbox"
// }
// }
// }
// });
///////////////////////////
// Qiniu storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// "type": "qiniu",
// "bucket": "BUCKET",
// "access_key": "ACCESSKEY",
// "secret_key": "SECRETKEY"
// }
// }
// });
///////////////////////////
// Replicate storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// type: "replicate",
// local_sub_storage: {
// type: "memory"
// },
// remote_sub_storage: {
// "type": "memory"
// }
// }
// }
// });
///////////////////////////
// Crypt storage
///////////////////////////
// return g.run({
// type: "query",
// sub_storage: {
// type: "uuid",
// sub_storage: {
// type: "crypt",
// key: {"alg": "A256GCM", "ext": true,
// "k": "seeaLzpu8dHG07bO2ANH2GywbTqs_zrs4Vq8zmtYeE4",
// "key_ops": ["encrypt", "decrypt"], "kty": "oct"},
// sub_storage: {
// type: "indexeddb",
// database: "test427"
// }
// }
// }
// });
global.gadget = this;
global.defer.resolve();
}) })
.declareMethod('run', function (jio_options) { .declareMethod('run', function (jio_options) {
var jio; test('Test "' + jio_options.type + '"scenario', function () {
var jio;
stop();
expect(14);
try { try {
jio = jIO.createJIO(jio_options); jio = jIO.createJIO(jio_options);
} catch (error) { } catch (error) {
console.error(error.stack); console.error(error.stack);
console.error(error);
throw error;
}
// Try to fetch inexistent document
jio.get("inexistent")
.fail(function (error) {
console.error(error); console.error(error);
if (error.status_code !== 404) { throw error;
throw error; }
}
equal(error.status_code, 404, "404 if inexistent"); // Try to fetch inexistent document
jio.get("inexistent")
// Post a document without ID .fail(function (error) {
return jio.post({"title": "I don't have ID éà&\n"}); console.error(error);
}) if (error.status_code !== 404) {
.then(function (doc_id) { throw error;
ok(doc_id, "Document without ID created (" + doc_id + ")"); }
// Fetch the newly created document equal(error.status_code, 404, "404 if inexistent");
return RSVP.all([
jio.get(doc_id), // Post a document without ID
doc_id return jio.post({"title": "I don't have ID éà&\n"});
]); })
}) .then(function (doc_id) {
.then(function (result_list) { ok(doc_id, "Document without ID created (" + doc_id + ")");
var doc = result_list[0], // Fetch the newly created document
doc_id = result_list[1]; return RSVP.all([
deepEqual(doc, {"title": "I don't have ID éà&\n"}, jio.get(doc_id),
"Document correctly fetched"); doc_id
// Remove the doc ]);
return jio.remove(doc_id); })
}) .then(function (result_list) {
.then(function (doc_id) { var doc = result_list[0],
ok(doc_id, "Document removed"); doc_id = result_list[1];
// Create some documents to check allDocs deepEqual(doc, {"title": "I don't have ID éà&\n"},
return RSVP.all([ "Document correctly fetched");
jio.put("id1", {"title": "1 ID", "int_index": 1}), // Remove the doc
jio.put("id2", {"title": "2 ID", "int_index": 2}), return jio.remove(doc_id);
jio.put("id3", {"title": "3 ID", "int_index": 3}) })
]); .then(function (doc_id) {
}) ok(doc_id, "Document removed");
.then(function (all_doc_id) { // Create some documents to check allDocs
equal(all_doc_id[0], "id1", "Document 1 correctly created"); return RSVP.all([
equal(all_doc_id[1], "id2", "Document 2 correctly created"); jio.put("id1", {"title": "1 ID", "int_index": 1}),
equal(all_doc_id[2], "id3", "Document 3 correctly created"); jio.put("id2", {"title": "2 ID", "int_index": 2}),
jio.put("id3", {"title": "3 ID", "int_index": 3})
]);
})
.then(function (all_doc_id) {
equal(all_doc_id[0], "id1", "Document 1 correctly created");
equal(all_doc_id[1], "id2", "Document 2 correctly created");
equal(all_doc_id[2], "id3", "Document 3 correctly created");
// // Default allDocs call // // Default allDocs call
// return jio.allDocs(); // return jio.allDocs();
...@@ -94,313 +248,94 @@ ...@@ -94,313 +248,94 @@
// } // }
// }, "default allDocs OK"); // }, "default allDocs OK");
// Filter the result // Filter the result
console.log("START ALLDOCS"); console.log("START ALLDOCS");
return jio.allDocs({ return jio.allDocs({
query: 'title: "2 ID"', query: 'title: "2 ID"',
select_list: ["int_index"] select_list: ["int_index"]
}); });
}) })
.then(function (result) { .then(function (result) {
deepEqual(result, { deepEqual(result, {
data: { data: {
rows: [{ rows: [{
doc: {}, doc: {},
id: "id2", id: "id2",
value: {int_index: 2} value: {int_index: 2}
}], }],
total_rows: 1 total_rows: 1
} }
}, "filter allDocs OK"); }, "filter allDocs OK");
// XXX Check include docs, sort, limit, select // XXX Check include docs, sort, limit, select
}) })
.then(function () { .then(function () {
return jio.getAttachment("inexistent", "enclosure") return jio.getAttachment("inexistent", "enclosure")
.fail(function (error) { .fail(function (error) {
equal(error.status_code, 404, "404 if inexistent"); equal(error.status_code, 404, "404 if inexistent");
console.log(error); console.log(error);
}); });
}) })
.then(function () {
return jio.put("foo❤/test.txt", {});
})
.then(function () {
return jio.putAttachment(
"foo❤/test.txt",
"enclosure",
new Blob(["fooé\nbar测试四😈"], {type: "text/plain"})
);
})
.then(function () {
ok(true, "Attachment stored");
return jio.getAttachment("foo❤/test.txt", "enclosure");
})
.then(function (blob) {
return jIO.util.readBlobAsText(blob);
})
.then(function (result) {
equal(result.target.result, "fooé\nbar测试四😈", "Attachment correctly fetched");
return jio.get("foo❤/test.txt");
})
.then(function (doc) {
deepEqual(doc, {}, "Document correctly fetched");
return jio.allAttachments("foo❤/test.txt");
})
.then(function (doc) {
deepEqual(doc, {
enclosure: {}
},
"Attachment list correctly fetched");
return jio.removeAttachment("foo❤/test.txt", "enclosure");
})
.then(function () {
ok("Attachment removed");
})
.then(function () {
return jio.repair();
})
.fail(function (error) {
console.error("---");
console.error(error.stack);
console.error(error);
ok(false, error);
})
.always(function () {
start();
});
});
module("scenario"); .then(function () {
/////////////////////////// return jio.put("foo❤/test.txt", {});
// Memory storage })
///////////////////////////
test('Test Memory Storage scenario', function () { .then(function () {
stop(); return jio.putAttachment(
expect(14); "foo❤/test.txt",
return global.defer.promise "enclosure",
.then(function () { new Blob(["fooé\nbar测试四😈"], {type: "text/plain"})
return global.gadget.run({ );
type: "query", })
sub_storage: {
type: "uuid", .then(function () {
sub_storage: { ok(true, "Attachment stored");
type: "union", return jio.getAttachment("foo❤/test.txt", "enclosure");
storage_list: [{ })
type: "memory"
}] .then(function (blob) {
} return jIO.util.readBlobAsText(blob);
} })
});
}); .then(function (result) {
}); equal(result.target.result, "fooé\nbar测试四😈", "Attachment correctly fetched");
/////////////////////////// return jio.get("foo❤/test.txt");
// Local storage
/////////////////////////// })
test('Test Local Storage scenario', function () { .then(function (doc) {
stop(); deepEqual(doc, {}, "Document correctly fetched");
expect(14);
return global.defer.promise return jio.allAttachments("foo❤/test.txt");
.then(function () { })
return global.gadget.run({ .then(function (doc) {
type: "query", deepEqual(doc, {
sub_storage: { enclosure: {}
type: "uuid", },
sub_storage: { "Attachment list correctly fetched");
type: "document",
document_id: "/", return jio.removeAttachment("foo❤/test.txt", "enclosure");
sub_storage: { })
type: "zip",
sub_storage: { .then(function () {
type: "local" ok("Attachment removed");
} })
}
} .then(function () {
} return jio.repair();
}); })
});
}); .fail(function (error) {
/////////////////////////// console.error("---");
// WebSQL storage console.error(error.stack);
/////////////////////////// console.error(error);
test('Test WebSQL Storage scenario', function () { ok(false, error);
stop(); })
expect(14); .always(function () {
return global.defer.promise start();
.then(function () { });
return global.gadget.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
"type": "websql",
"database": "test"
}
}
});
});
});
///////////////////////////
// IndexedDB storage
///////////////////////////
test('Test IndexedDB Storage scenario', function () {
stop();
expect(14);
return global.defer.promise
.then(function () {
return global.gadget.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
"type": "indexeddb",
"database": "test"
}
}
});
});
});
///////////////////////////
// DAV storage
///////////////////////////
/*
test('Test DAV Storage scenario', function () {
stop();
expect(14);
return global.defer.promise
.then(function () {
return global.gadget.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "drivetojiomapping",
sub_storage: {
"type": "dav",
"url": "DAVURL",
"basic_login": btoa("LOGIN:PASSWD")
}
}
}
});
});
});
*/
///////////////////////////
// Dropbox storage
///////////////////////////
/*
test('Test Dropbox Storage scenario', function () {
stop();
expect(14);
return global.defer.promise
.then(function () {
return global.gadget.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "drivetojiomapping",
sub_storage: {
"type": "dropbox",
"access_token" : "TOKEN",
"root" : "dropbox"
}
}
}
});
});
});
*/
///////////////////////////
// Qiniu storage
///////////////////////////
/*
test('Test Qiniu Storage scenario', function () {
stop();
expect(14);
return global.defer.promise
.then(function () {
return global.gadget.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
"type": "qiniu",
"bucket": "BUCKET",
"access_key": "ACCESSKEY",
"secret_key": "SECRETKEY"
}
}
});
});
});
*/
///////////////////////////
// Replicate storage
///////////////////////////
test('Test Replicate Storage scenario', function () {
stop();
expect(14);
return global.defer.promise
.then(function () {
return global.gadget.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "replicate",
local_sub_storage: {
type: "memory"
},
remote_sub_storage: {
"type": "memory"
}
}
}
});
});
});
///////////////////////////
// Crypt storage
///////////////////////////
test('Test Crypt Storage scenario', function () {
stop();
expect(14);
return global.defer.promise
.then(function () {
return global.gadget.run({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "crypt",
key: {"alg": "A256GCM", "ext": true,
"k": "seeaLzpu8dHG07bO2ANH2GywbTqs_zrs4Vq8zmtYeE4",
"key_ops": ["encrypt", "decrypt"], "kty": "oct"},
sub_storage: {
type: "indexeddb",
database: "test427"
}
}
}
});
}); });
}); });
}(window, QUnit, jIO, rJS, RSVP)); }(window, QUnit, jIO, rJS));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OfficeJS Coverage Scenario</title>
<script src="../node_modules/rsvp/dist/rsvp-2.0.4.js"></script>
<script src="../dist/jio-latest.js"></script>
<script src="../src/jio.storage/saferepairstorage.js"></script>
<link rel="stylesheet" href="../node_modules/grunt-contrib-qunit/test/libs/qunit.css" type="text/css" media="screen"/>
<script src="../node_modules/grunt-contrib-qunit/test/libs/qunit.js" type="text/javascript"></script>
<script src="scenario_officejs.js"></script>
</head>
<body>
<h1 id="qunit-header">OfficeJS Coverage Scenario</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<div id="qunit-fixture">test markup, will be hidden</div>
</body>
</html>
/*global Blob*/
/*jslint nomen: true, maxlen: 80*/
(function (QUnit, jIO, Blob) {
"use strict";
var test = QUnit.test,
// equal = QUnit.equal,
expect = QUnit.expect,
ok = QUnit.ok,
stop = QUnit.stop,
start = QUnit.start,
deepEqual = QUnit.deepEqual,
module = QUnit.module,
ATTACHMENT = 'data',
i,
name_list = ['get', 'post', 'put', 'remove', 'buildQuery',
'putAttachment', 'getAttachment', 'allAttachments'];
///////////////////////////////////////////////////////
// Fake Storage
///////////////////////////////////////////////////////
function resetCount(count) {
for (i = 0; i < name_list.length; i += 1) {
count[name_list[i]] = 0;
}
}
function MockStorage(spec) {
this._erp5_storage = jIO.createJIO({
type: "erp5",
url: "http://example.org"
});
this._sub_storage = jIO.createJIO({
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "memory"
}
}
});
this._options = spec.options;
resetCount(spec.options.count);
}
function mockFunction(name) {
MockStorage.prototype[name] = function () {
this._options.count[name] += 1;
if (this._options.mock.hasOwnProperty(name)) {
return this._options.mock[name].apply(this, arguments);
}
return this._sub_storage[name].apply(this._sub_storage, arguments);
};
}
for (i = 0; i < name_list.length; i += 1) {
mockFunction(name_list[i]);
}
MockStorage.prototype.hasCapacity = function (name) {
return this._erp5_storage.hasCapacity(name);
};
jIO.addStorage('mock', MockStorage);
///////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////
function putFullDoc(storage, id, doc, attachment) {
return storage.put(id, doc)
.push(function () {
return storage.putAttachment(
id,
ATTACHMENT,
attachment
);
});
}
function equalStorage(storage, doc_tuple_list) {
return storage.allDocs()
.push(function (result) {
var i,
promise_list = [];
for (i = 0; i < result.data.rows.length; i += 1) {
promise_list.push(RSVP.all([
result.data.rows[i].id,
storage.get(result.data.rows[i].id),
storage.getAttachment(result.data.rows[i].id, ATTACHMENT)
]));
}
return RSVP.all(promise_list);
})
.push(function (result) {
deepEqual(result, doc_tuple_list, 'Storage content');
});
}
function isEmptyStorage(storage) {
return equalStorage(storage, []);
}
function equalRemoteStorageCallCount(mock_count, expected_count) {
for (i = 0; i < name_list.length; i += 1) {
if (!expected_count.hasOwnProperty(name_list[i])) {
expected_count[name_list[i]] = 0;
}
}
deepEqual(mock_count, expected_count, 'Expected method call count');
}
///////////////////////////////////////////////////////
// Module
///////////////////////////////////////////////////////
module("scenario_officejs", {
setup: function () {
this.remote_mock_options = {
mock: {
remove: function () {
throw new Error('remove not supported');
},
removeAttachment: function () {
throw new Error('removeAttachment not supported');
},
allAttachments: function () {
return {data: null};
},
post: function (doc) {
var context = this;
return this._sub_storage.post(doc)
.push(function (post_id) {
context._options.last_post_id = post_id;
return post_id;
});
}
},
count: {}
};
this.jio = jIO.createJIO({
type: "replicate",
query: {
query: 'portal_type:"Foo"',
sort_on: [["modification_date", "descending"]]
},
signature_hash_key: 'modification_date',
use_remote_post: true,
conflict_handling: 1,
check_local_attachment_modification: true,
check_local_attachment_creation: true,
check_remote_attachment_modification: true,
check_remote_attachment_creation: true,
check_remote_attachment_deletion: true,
check_local_deletion: false,
parallel_operation_amount: 10,
parallel_operation_attachment_amount: 10,
local_sub_storage: {
type: "query",
sub_storage: {
type: "uuid",
sub_storage: {
type: "memory"
}
}
},
signature_sub_storage: {
type: "query",
sub_storage: {
type: "memory"
}
},
remote_sub_storage: {
type: "saferepair",
sub_storage: {
type: "mock",
options: this.remote_mock_options
}
}
});
}
});
///////////////////////////////////////////////////////
// Do nothing cases
///////////////////////////////////////////////////////
test("empty: nothing to do", function () {
expect(2);
stop();
var test = this;
this.jio.repair()
.then(function () {
return RSVP.all([
isEmptyStorage(test.jio),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("allready synced: nothing to do", function () {
expect(2);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
blob = new Blob(['a']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(test.jio, [[doc_id, doc, blob]]),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////
// Remote creation
///////////////////////////////////////////////////////
test("remote document creation: copy", function () {
expect(2);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
blob = new Blob(['a']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(test.jio, [[doc_id, doc, blob]]),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1, get: 1, getAttachment: 1, allAttachments: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////
// Remote modification
///////////////////////////////////////////////////////
test("remote document modification: copy", function () {
expect(2);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
doc2 = {title: doc_id + 'a', portal_type: "Foo", modification_date: 'b'},
blob = new Blob(['a']),
blob2 = new Blob(['b']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
return putFullDoc(test.jio.__storage._remote_sub_storage, doc_id, doc2,
blob2);
})
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(test.jio, [[doc_id, doc2, blob2]]),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1, get: 1, getAttachment: 1, allAttachments: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////
// Remote hide
///////////////////////////////////////////////////////
test("remote document deletion: delete", function () {
expect(2);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
blob = new Blob(['a']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
test.remote_mock_options.mock.buildQuery = function () {
return [];
};
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
isEmptyStorage(test.jio),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////
// Local creation
///////////////////////////////////////////////////////
test("local document creation: copy", function () {
expect(3);
stop();
var test = this,
doc_id = 'abc',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
blob = new Blob(['a']);
putFullDoc(this.jio, doc_id, doc, blob)
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(
test.jio,
[[test.remote_mock_options.last_post_id, doc, blob]]
),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1, post: 1, putAttachment: 1, allAttachments: 1}
)
]);
})
.then(function () {
return equalStorage(
test.jio.__storage._remote_sub_storage,
[[test.remote_mock_options.last_post_id, doc, blob]]
);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////
// Local modification
///////////////////////////////////////////////////////
test("local document modification: copy", function () {
expect(2);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
doc2 = {title: doc_id + 'a', portal_type: "Foo", modification_date: 'b'},
blob = new Blob(['a']),
blob2 = new Blob(['b']),
last_id;
putFullDoc(this.jio, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
last_id = test.remote_mock_options.last_post_id;
return putFullDoc(test.jio, last_id, doc2, blob2);
})
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(
test.jio.__storage._remote_sub_storage,
[[last_id, doc2, blob2]]
),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1, put: 1,
allAttachments: 1, putAttachment: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////
// Conflict
///////////////////////////////////////////////////////
test("both modification: keep local", function () {
expect(2);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
doc2 = {title: doc_id + 'a', portal_type: "Foo", modification_date: 'b'},
doc3 = {title: doc_id + 'c', portal_type: "Foo", modification_date: 'c'},
blob = new Blob(['a']),
blob2 = new Blob(['b']),
blob3 = new Blob(['c']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
return RSVP.all([
putFullDoc(test.jio.__storage._remote_sub_storage, doc_id,
doc2, blob2),
putFullDoc(test.jio, doc_id, doc3, blob3)
]);
})
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(
test.jio.__storage._remote_sub_storage,
[[doc_id, doc3, blob3]]
),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1, put: 1,
allAttachments: 1, putAttachment: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("local modification / frozen remote", function () {
expect(1);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
doc2 = {title: doc_id + 'a', portal_type: "Foo", modification_date: 'b'},
blob = new Blob(['a']),
blob2 = new Blob(['b']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
return putFullDoc(test.jio, doc_id, doc2, blob2);
})
.then(function () {
test.remote_mock_options.mock.put = function (id) {
if (id === doc_id) {
throw new jIO.util.jIOError('put not allowed', 403);
}
return id;
};
test.remote_mock_options.mock.putAttachment = function (id) {
if (id === doc_id) {
throw new jIO.util.jIOError('putattachment not allowed', 403);
}
return id;
};
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{
"allAttachments": 1,
"buildQuery": 1,
"post": 1,
"put": 1,
"putAttachment": 2
}
);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
///////////////////////////////////////////////////////
// Local deletion (aka, people playing manually with the browser storage)
///////////////////////////////////////////////////////
test("local document deletion: do nothing", function () {
expect(3);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
blob = new Blob(['a']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
return test.jio.remove(doc_id);
})
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
isEmptyStorage(test.jio),
equalStorage(
test.jio.__storage._remote_sub_storage,
[[doc_id, doc, blob]]
),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("local attachment deletion: do nothing", function () {
expect(2);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
blob = new Blob(['a']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
return test.jio.removeAttachment(doc_id, ATTACHMENT);
})
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(
test.jio.__storage._remote_sub_storage,
[[doc_id, doc, blob]]
),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
test("local deletion / remote modification", function () {
expect(3);
stop();
var test = this,
doc_id = 'foo_module/1',
doc = {title: doc_id, portal_type: "Foo", modification_date: 'a'},
doc2 = {title: doc_id + 'a', portal_type: "Foo", modification_date: 'b'},
blob = new Blob(['a']),
blob2 = new Blob(['b']);
putFullDoc(this.jio.__storage._remote_sub_storage, doc_id, doc, blob)
.then(function () {
return test.jio.repair();
})
.then(function () {
return RSVP.all([
putFullDoc(test.jio.__storage._remote_sub_storage, doc_id,
doc2, blob2),
test.jio.remove(doc_id)
]);
})
.then(function () {
resetCount(test.remote_mock_options.count);
return test.jio.repair();
})
.then(function () {
return RSVP.all([
equalStorage(
test.jio,
[]
),
equalStorage(
test.jio.__storage._remote_sub_storage,
[[doc_id, doc2, blob2]]
),
equalRemoteStorageCallCount(
test.remote_mock_options.count,
{buildQuery: 1}
)
]);
})
.fail(function (error) {
ok(false, error);
})
.always(function () {
start();
});
});
}(QUnit, jIO, Blob));
/*jslint indent:2,maxlen:80,nomen:true*/
/*global jIO, RSVP*/
(function (jIO, RSVP) {
"use strict";
/**
* The jIO SafeRepairStorage extension
*
* @class SafeRepairStorage
* @constructor
*/
function SafeRepairStorage(spec) {
this._sub_storage = jIO.createJIO(spec.sub_storage);
this._id_dict = {};
}
SafeRepairStorage.prototype.get = function () {
return this._sub_storage.get.apply(this._sub_storage, arguments);
};
SafeRepairStorage.prototype.allAttachments = function () {
return this._sub_storage.allAttachments.apply(this._sub_storage, arguments);
};
SafeRepairStorage.prototype.post = function () {
return this._sub_storage.post.apply(this._sub_storage, arguments);
};
SafeRepairStorage.prototype.put = function (id, doc) {
var storage = this;
return this._sub_storage.put.apply(this._sub_storage, arguments)
.push(undefined, function (error) {
if (error instanceof jIO.util.jIOError &&
error.status_code === 403) {
if (storage._id_dict[id]) {
return storage._sub_storage.put(storage._id_dict[id], doc);
}
return storage._sub_storage.post(doc)
.push(function (sub_id) {
storage._id_dict[id] = sub_id;
return sub_id;
});
}
});
};
SafeRepairStorage.prototype.remove = function () {
return;
};
SafeRepairStorage.prototype.getAttachment = function () {
return this._sub_storage.getAttachment.apply(this._sub_storage, arguments);
};
SafeRepairStorage.prototype.putAttachment = function (id, attachment_id,
attachment) {
var storage = this;
return this._sub_storage.putAttachment.apply(this._sub_storage, arguments)
.push(undefined, function (error) {
if (error instanceof jIO.util.jIOError &&
error.status_code === 403) {
return new RSVP.Queue()
.push(function () {
if (storage._id_dict[id]) {
return storage._id_dict[id];
}
return storage._sub_storage.get(id)
.push(function (doc) {
return storage._sub_storage.post(doc);
});
})
.push(function (sub_id) {
storage._id_dict[id] = sub_id;
return storage._sub_storage.putAttachment(sub_id, attachment_id,
attachment);
});
}
});
};
SafeRepairStorage.prototype.removeAttachment = function () {
return;
};
SafeRepairStorage.prototype.repair = function () {
return this._sub_storage.repair.apply(this._sub_storage, arguments);
};
SafeRepairStorage.prototype.hasCapacity = function (name) {
return this._sub_storage.hasCapacity(name);
};
SafeRepairStorage.prototype.buildQuery = function () {
return this._sub_storage.buildQuery.apply(this._sub_storage,
arguments);
};
jIO.addStorage('saferepair', SafeRepairStorage);
}(jIO, RSVP));
...@@ -53,11 +53,6 @@ ...@@ -53,11 +53,6 @@
<script src="jio.storage/zipstorage.tests.js"></script> <script src="jio.storage/zipstorage.tests.js"></script>
<script src="jio.storage/gdrivestorage.tests.js"></script> <script src="jio.storage/gdrivestorage.tests.js"></script>
<script src="jio.storage/websqlstorage.tests.js"></script> <script src="jio.storage/websqlstorage.tests.js"></script>
<script src="../node_modules/renderjs/dist/renderjs-latest.js"></script>
<script src="../examples/scenario.js"></script>
<script src="../examples/scenario_officejs.js"></script>
<!--script src="../lib/jquery/jquery.min.js"></script> <!--script src="../lib/jquery/jquery.min.js"></script>
<script src="../src/jio.storage/xwikistorage.js"></script> <script src="../src/jio.storage/xwikistorage.js"></script>
<script src="jio.storage/xwikistorage.tests.js"></script--> <script src="jio.storage/xwikistorage.tests.js"></script-->
......
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