diff --git a/test/jiotests.js b/test/jiotests.js index aa5d39a8d3d5c916089bdc1032061eba38b0e061..7f5e4e7c5fe019405876a23e45922de85e23cbe1 100644 --- a/test/jiotests.js +++ b/test/jiotests.js @@ -1,6 +1,5 @@ (function () { var thisfun = function(loader) { var JIO = loader.JIO, - LocalOrCookieStorage = loader.LocalOrCookieStorage, sjcl = loader.sjcl, Base64 = loader.Base64, $ = loader.jQuery; @@ -19,12 +18,28 @@ contains = function (array,content) { } return false; }, -clean_up_local_storage_function = function(){ - var k, storageObject = LocalOrCookieStorage.getAll(); +// localStorage wrapper +localstorage = { + clear: function () { + return localStorage.clear(); + }, + getItem: function (item) { + var value = localStorage.getItem(item); + return value === null? null: JSON.parse(value); + }, + setItem: function (item,value) { + return localStorage.setItem(item,JSON.stringify (value)); + }, + removeItem: function (item) { + return localStorage.removeItem(item); + } +}, +cleanUpLocalStorage = function(){ + var k, storageObject = localstorage.getAll(); for (k in storageObject) { var splitk = k.split('/'); if ( splitk[0] === 'jio' ) { - LocalOrCookieStorage.deleteItem(k); + localstorage.removeItem(k); } } var d = document.createElement ('div'); @@ -34,11 +49,10 @@ clean_up_local_storage_function = function(){ localStorage.clear(); }, base_tick = 30000, -basic_test_function_generator = function(o,res,value,message) { +basicTestFunctionGenerator = function(o,res,value,message) { return function(err,val) { - var jobstatus = (err?'fail':'done'), - val = ( isEmptyObject(value) && isUUID(val._id) ) ? {} : val; + var jobstatus = (err?'fail':'done'); switch (res) { case 'status': @@ -56,15 +70,15 @@ basic_test_function_generator = function(o,res,value,message) { deepEqual (val,value,message); }; }, -basic_spy_function = function(o,res,value,message,fun) { +basicSpyFunction = function(o,res,value,message,fun) { fun = fun || 'f'; - o[fun] = basic_test_function_generator(o,res,value,message); + o[fun] = basicTestFunctionGenerator(o,res,value,message); o.t.spy(o,fun); }, -basic_tick_function = function (o) { +basicTickFunction = function (o) { var tick, fun, i = 1; - tick = 1000; + tick = 10000; fun = fun || 'f'; if (typeof arguments[i] === 'number') { @@ -83,7 +97,7 @@ basic_tick_function = function (o) { } }, // debug function to show custumized log at the bottom of the page -my_log = function (html_string) { +myLog = function (html_string) { document.querySelector ('div#log').innerHTML += html_string + '<hr/>'; }, getXML = function (url) { @@ -95,181 +109,88 @@ getXML = function (url) { objectifyDocumentArray = function (array) { var obj = {}, k; for (k = 0; k < array.length; k += 1) { - obj[array[k].id] = array[k]; + obj[array[k]._id] = array[k]; } return obj; }, -addFileToLocalStorage = function (user,appid,file) { - var i, l, found = false, filenamearray, - userarray = LocalOrCookieStorage.getItem('jio/local_user_array') || []; - for (i = 0, l = userarray.length; i < l; i+= 1) { - if (userarray[i] === user) { found = true; } - } - if (!found) { - userarray.push(user); - LocalOrCookieStorage.setItem('jio/local_user_array',userarray); - LocalOrCookieStorage.setItem( - 'jio/local_file_name_array/'+user+'/'+appid,[file._id]); - } else { - filenamearray = - LocalOrCookieStorage.getItem( - 'jio/local_file_name_array/'+user+'/'+appid) || []; - filenamearray.push(file._id); - LocalOrCookieStorage.setItem( - 'jio/local_file_name_array/'+user+'/'+appid, - filenamearray); - LocalOrCookieStorage.setItem( - 'jio/local/'+user+'/'+appid+'/'+file._id, - file); - } - LocalOrCookieStorage.setItem( - 'jio/local/'+user+'/'+appid+'/'+file._id, - file); +getLastJob = function (id) { + return (localstorage.getItem("jio/job_array/"+id) || [undefined]).pop(); }, -removeFileFromLocalStorage = function (user,appid,file) { - var i, l, newarray = [], - filenamearray = - LocalOrCookieStorage.getItem( - 'jio/local_file_name_array/'+user+'/'+appid) || []; - for (i = 0, l = filenamearray.length; i < l; i+= 1) { - if (filenamearray[i] !== file._id) { - newarray.push(filenamearray[i]); - } - } - LocalOrCookieStorage.setItem('jio/local_file_name_array/'+user+'/'+appid, - newarray); - LocalOrCookieStorage.deleteItem( - 'jio/local/'+user+'/'+appid+'/'+file._id); -}, -makeRevsAccordingToRevsInfo = function (revs,revs_info) { - var i, j; - for (i = 0; i < revs.start; i+= 1) { - for (j = 0; j < revs_info.length; j+= 1) { - var id = revs_info[j].rev.split('-'); id.shift(); id = id.join('-'); - if (revs.ids[i] === id) { - revs.ids[i] = revs_info[j].rev.split('-')[0]; +generateTools = function (sinon) { + var o = {}; + o.t = sinon; + o.clock = o.t.sandbox.useFakeTimers(); + o.clock.tick(base_tick); + o.spy = basicSpyFunction; + o.tick = basicTickFunction; + o.testLastJobLabel = function (label, mess) { + deepEqual( + getLastJob(o.jio.getId()).command.label, + label, + mess + ); + }; + o.testLastJobId = function (id, mess) { + deepEqual( + getLastJob(o.jio.getId()).id, + id, + mess + ); + }; + o.testLastJobWaitForTime = function (mess) { + ok(getLastJob(o.jio.getId()).status.waitfortime > 0, mess); + }; + o.testLastJobWaitForJob = function (job_id_array, mess) { + deepEqual( + getLastJob(o.jio.getId()).status.waitforjob, + job_id_array, + mess + ); + }; + o.waitUntilAJobExists = function (timeout) { + var cpt = 0 + while (true) { + if (getLastJob(o.jio.getId()) !== undefined) { break; } + if (timeout >= cpt) { + ok(false, "no job added to the queue"); + break; + } + o.clock.tick(25); + cpt += 25; } - } -}, -checkRev = function (rev) { - if (typeof rev === 'string') { - if (rev.split('-').length > 1 && - parseInt(rev.split('-')[0],10) > 0) { - return rev; - } - } - return 'ERROR: not a good revision!'; -}, -checkConflictRow = function (row) { - var fun; - if (typeof row === 'object') { - if (row.value && typeof row.value._solveConflict === 'function') { - fun = row.value._solveConflict; - row.value._solveConflict = 'function'; - } - } - return fun; -}, -getHashFromRev = function (rev) { - var id = rev; - if (typeof id === 'string') { - id = id.split('-'); - id.shift(); id = id.join('-'); - } - return id; -}, -revs_infoContains = function (revs_info, rev) { - var i; - if (typeof revs_info !== 'object') { - return undefined; - } - for (i = 0; i < revs_info.length || 0; i+= 1) { - if (revs_info[i].rev && revs_info[i].rev === rev) { - return true; - } - } - return false; -}, -isUUID = function( _id ){ - - var re = /^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$/; - if ( re.test( _id ) ){ - return true; - } else { - return false; - } -}, -isEmptyObject = function( obj) { - var key; - - if (obj.length && obj.length > 0){ - return false; - } - if (obj.length && obj.length === 0){ - return true; - } - for (key in obj) { - if (hasOwnProperty.call(obj, key)){ - return false; + }; + o.waitUntilLastJobIs = function (state) { + while (true) { + if (getLastJob(o.jio.getId()) === undefined) { + ok(false, "a job is never called"); + break; + } + if (getLastJob(o.jio.getId()).status.label === state) { + break; + } + o.clock.tick(25); } - } - return true; -}, + }; + return o; +}; //// end tools //// test methods //// -checkReply = function(o,tick,fun){ - basic_tick_function(o,tick,fun); -}, -checkFile = function (response, o, tick, value, fun) { - o.tmp = localstorage.getItem('jio/local/'+o.username+'/jiotests/'+ - response.id+'/'+response.rev ); - - // remove everything not needed for basic response - o.tmp.ok = true; - delete o.tmp._revisions; - delete o.tmp._revs_info; - delete o.tmp.content; - - if (o.tmp) { - deepEqual (o.tmp,{ - "ok":response.ok, - "_id":response.id, - "_rev":response.rev, - },'document was created or updated'); - } else { - ok (false, 'document was not created or updated'); - } -}, - -checkTreeNode = function (response,o,tick,value,fun) { - o.tmp = localstorage.getItem('jio/local/'+o.username+'/jiotests/'+ - response.id+'/revision_tree' ); - - if (o.tmp) { - deepEqual (o.tmp,o.buildTestTree,'tree node was created'); - } else { - ok (false, 'tree node was not created'); - } -}; - - //// QUnit Tests //// - module ('Jio Global tests'); test ( "Jio simple methods", function () { - var clock = this.sandbox.useFakeTimers(); clock.tick(base_tick); // Test Jio simple methods // It checks if we can create several instance of jio at the same // time. Checks if they don't overlap informations, if they are // started and stopped correctly and if they are ready when they // have to be ready. - var o = {}; + var o = generateTools(this); + o.jio = JIO.newJio(); ok ( o.jio, 'a new jio -> 1'); @@ -312,917 +233,776 @@ test ( "Jio simple methods", function () { // o.jio.stop(); // }); -module ( 'Jio Dummy Storages' ); +module ( "Jio Dummy Storages" ); -test ('All tests', function () { - // Tests all dummy storages from jio.dummystorages.js - // It is simple tests, but they will be used by replicate storage later - // for sync operation. +test ("All requests ok", function () { + // Tests the request methods and the response with dummy storages - var o = {}; o.t = this; o.clock = o.t.sandbox.useFakeTimers(); - o.clock.tick(base_tick); - o.spy = basic_spy_function; - o.tick = basic_tick_function; + var o = generateTools(this); // All Ok Dummy Storage - o.jio = JIO.newJio({'type':'dummyallok'}); - - // post empty - o.jio.post({}, - function(err, response) { - o.spy(o,'value',{"ok":true, "id":response.id, "rev":response.rev}, - 'dummyallok post/create empty object'); - o.f(response); - }); + o.jio = JIO.newJio({"type": "dummyallok"}); + + // post empty document, some storage can create there own id (like couchdb + // generates uuid). In this case, the dummy storage write an undefined id. + o.spy(o, "value", {"ok": true, "id": undefined}, + "Post document with empty id"); + o.jio.post({}, o.f); o.tick(o); - // post - o.jio.post({"content":"basic_content"}, - function(err, response) { - o.spy(o,'value',{"ok":true, "id":response.id, "rev":response.rev}, - 'dummyallok post/create object'); - o.f(response); - }); + // post non empty document + o.spy(o, "value", {"ok": true, "id": "file"}, "Post non empty document"); + o.jio.post({"_id": "file", "title": "myFile"}, o.f); o.tick(o); - // put - o.jio.put({"_id":"file","content":"basic_content"}, - function(err, response) { - o.spy(o,'value',{"ok":true, "id":"file", "rev":response.rev}, - 'dummyallok put create object'); - o.f(response); - }); + // put without id + // error 20 -> document id required + o.spy(o, "status", 20, "Put document with empty id"); + o.jio.put({}, o.f); o.tick(o); - /* + // put non empty document + o.spy(o, "value", {"ok": true, "id": "file"}, "Put non empty document"); + o.jio.put({"_id": "file", "title": "myFile"}, o.f); + o.tick(o); - // load - o.spy(o,'value',{_id:'file',content:'content',_last_modified:15000, - _creation_date:10000},'dummyallok loading'); - o.jio.get('file',o.f); + // put an attachment without attachment id + // error 22 -> attachment id required + o.spy(o, "status", 22, + "Put attachment without id"); + o.jio.putAttachment({ + "id": "file", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); o.tick(o); - // remove - o.spy(o,'value',{ok:true,id:"file"},'dummyallok removing'); - o.jio.remove({_id:'file'},o.f); + // put an attachment + o.spy(o, "value", {"ok": true, "id": "file/attmt"}, + "Put attachment"); + o.jio.putAttachment({ + "id": "file/attmt", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); o.tick(o); - // get list - o.spy (o,'value',{ - total_rows:2, - rows:[{ - id:'file',key:'file', - value:{ - content:'filecontent', - _last_modified:15000, - _creation_date:10000 - } - },{ - id:'memo',key:'memo', - value:{ - content:'memocontent', - _last_modified:25000, - _creation_date:20000 - } - }] - },'dummyallok getting list'); - o.jio.allDocs({metadata_only:false},o.f); + // get document + o.spy(o, "value", {"_id": "file", "title": "get_title"}, "Get document"); + o.jio.get("file", o.f); + o.tick(o); + + // get attachment + o.spy(o, "value", "0123456789", "Get attachment"); + o.jio.get("file/attmt", o.f); o.tick(o); - o.jio.stop(); + // remove document + o.spy(o, "value", {"ok": true, "id": "file"}, "Remove document"); + o.jio.remove({"_id": "file"}, o.f); + o.tick(o); + + // remove attachment + o.spy(o, "value", {"ok": true, "id": "file/attmt"}, "Remove attachment"); + o.jio.remove({"_id": "file/attmt"}, o.f); + o.tick(o); + + // alldocs + // error 405 -> Method not allowed + o.spy(o, "status", 405, "AllDocs fail"); + o.jio.allDocs(o.f); + o.tick(o); - o.jio = JIO.newJio({'type':'dummyallok'}); - // save - o.spy(o,'value',{ok:true,id:'file'},'dummyallok saving1','f'); - o.spy(o,'value',{ok:true,id:'file2'},'dummyallok saving2','f2'); - o.spy(o,'value',{ok:true,id:'file3'},'dummyallok saving3','f3'); - o.jio.put({_id:'file',content:'content'},o.f); - o.jio.put({_id:'file2',content:'content2'},o.f2); - o.jio.put({_id:'file3',content:'content3'},o.f3); - o.tick(o, 1000, 'f'); - o.tick(o, 'f2'); - o.tick(o, 'f3'); o.jio.stop(); +}); + +test ("All requests fail", function () { + // Tests the request methods and the err object with dummy storages + + var o = generateTools(this); + + // All Ok Dummy Storage + o.jio = JIO.newJio({"type": "dummyallfail"}); + + // post empty document + // error 0 -> unknown + o.spy(o, "status", 0, "Post document with empty id"); + o.jio.post({}, o.f); + o.tick(o); + // test if the job still exists + if (getLastJob(o.jio.getId()) !== undefined) { + ok(false, "The job is not removed from the job queue"); + } - // All Fail Dummy Storage - o.jio = JIO.newJio({'type':'dummyallfail'}); - // save - o.spy (o,'status',0,'dummyallfail saving'); - o.jio.put({_id:'file',content:'content'},o.f); + // post non empty document + o.spy(o, "status", 0, "Post non empty document"); + o.jio.post({"_id": "file", "title": "myFile"}, o.f); o.tick(o); - // load - o.spy (o,'status',0,'dummyallfail loading'); - o.jio.get('file',o.f); + + // put without id + // error 20 -> document id required + o.spy(o, "status", 20, "Put document with empty id"); + o.jio.put({}, o.f); o.tick(o); - // remove - o.spy (o,'status',0,'dummyallfail removing'); - o.jio.remove({_id:'file'},o.f); + + // put non empty document + o.spy(o, "status", 0, "Put non empty document"); + o.jio.put({"_id": "file", "title": "myFile"}, o.f); o.tick(o); - // get list - o.spy (o,'status',0,'dummyallfail getting list'); + + // put an attachment without attachment id + // error 22 -> attachment id required + o.spy(o, "status", 22, + "Put attachment without id"); + o.jio.putAttachment({ + "id": "file", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); + o.tick(o); + + // put an attachment + o.spy(o, "status", 0, + "Put attachment"); + o.jio.putAttachment({ + "id": "file/attmt", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); + o.tick(o); + + // get document + o.spy(o, "status", 0, "Get document"); + o.jio.get("file", o.f); + o.tick(o); + + // get attachment + o.spy(o, "status", 0, "Get attachment"); + o.jio.get("file/attmt", o.f); + o.tick(o); + + // remove document + o.spy(o, "status", 0, "Remove document"); + o.jio.remove({"_id": "file"}, o.f); + o.tick(o); + + // remove attachment + o.spy(o, "status", 0, "Remove attachment"); + o.jio.remove({"_id": "file/attmt"}, o.f); + o.tick(o); + + // alldocs + // error 405 -> Method not allowed + o.spy(o, "status", 405, "AllDocs fail"); o.jio.allDocs(o.f); o.tick(o); + o.jio.stop(); +}); + +test ("All document not found", function () { + // Tests the request methods without document + + var o = generateTools(this); + + // All Ok Dummy Storage + o.jio = JIO.newJio({"type": "dummyallnotfound"}); - // All Not Found Dummy Storage - o.jio = JIO.newJio({'type':'dummyallnotfound'}); - // save - o.spy(o,'value',{ok:true,id:'file'},'dummyallnotfound saving'); - o.jio.put({_id:'file',content:'content'},o.f); + // post document + o.spy(o, "value", {"ok": true, "id": "file"}, "Post document"); + o.jio.post({"_id": "file", "title": "myFile"}, o.f); o.tick(o); - // load - o.spy(o,'status',404,'dummyallnotfound loading') - o.jio.get('file',o.f); + + // put document + o.spy(o, "value", {"ok": true, "id": "file"}, "Put document"); + o.jio.put({"_id": "file", "title": "myFile"}, o.f); o.tick(o); - // remove - o.spy(o,'value',{ok:true,id:'file'},'dummyallnotfound removing'); - o.jio.remove({_id:'file'},o.f); + + // put an attachment without attachment id + // error 22 -> attachment id required + o.spy(o, "status", 22, + "Put attachment without id"); + o.jio.putAttachment({ + "id": "file", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); o.tick(o); - // get list - o.spy(o,'status',404,'dummyallnotfound getting list'); - o.jio.allDocs (o.f); + + // put an attachment + o.spy(o, "value", {"ok": true, "id": "file/attmt"}, + "Put attachment"); + o.jio.putAttachment({ + "id": "file/attmt", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); o.tick(o); - o.jio.stop(); - */ + // get document + o.spy(o, "status", 404, "Get document"); + o.jio.get("file", o.f); + o.tick(o); + + // get attachment + o.spy(o, "status", 404, "Get attachment"); + o.jio.get("file/attmt", o.f); + o.tick(o); + + // remove document + o.spy(o, "status", 404, "Remove document"); + o.jio.remove({"_id": "file"}, o.f); + o.tick(o); + + // remove attachment + o.spy(o, "status", 404, "Remove attachment"); + o.jio.remove({"_id": "file/attmt"}, o.f); + o.tick(o); + + o.jio.stop(); }); -/* -module ( 'Jio Job Managing' ); - -test ('Simple Job Elimination', function () { - var clock = this.sandbox.useFakeTimers(); clock.tick(base_tick); - var o = {}, id = 0; - o.f1 = this.spy(); o.f2 = this.spy(); - - o.jio = JIO.newJio({type:'dummyallok',applicationname:'jiotests'}); - id = o.jio.getId(); - o.jio.put({_id:'file',content:'content'}, - {max_retry:1},o.f1); - ok(LocalOrCookieStorage.getItem('jio/job_array/'+id)[0], - 'job creation'); - o.jio.remove({_id:'file'},{max_retry:1},o.f2); - o.tmp = LocalOrCookieStorage.getItem('jio/job_array/'+id)[0]; - deepEqual(o.tmp.command.label,'remove','job elimination'); + +test ("All document found", function () { + // Tests the request methods with document + + var o = generateTools(this); + + // All Ok Dummy Storage + o.jio = JIO.newJio({"type": "dummyallfound"}); + + // post non empty document + o.spy(o, "status", 409, "Post document"); + o.jio.post({"_id": "file", "title": "myFile"}, o.f); + o.tick(o); + + // put non empty document + o.spy(o, "value", {"ok": true, "id": "file"}, "Put non empty document"); + o.jio.put({"_id": "file", "title": "myFile"}, o.f); + o.tick(o); + + // put an attachment without attachment id + // error 22 -> attachment id required + o.spy(o, "status", 22, + "Put attachment without id"); + o.jio.putAttachment({ + "id": "file", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); + o.tick(o); + + // put an attachment + o.spy(o, "value", {"ok": true, "id": "file/attmt"}, + "Put attachment"); + o.jio.putAttachment({ + "id": "file/attmt", + "data": "0123456789", + "mimetype": "text/plain" + }, o.f); + o.tick(o); + + // get document + o.spy(o, "value", {"_id": "file", "title": "get_title"}, "Get document"); + o.jio.get("file", o.f); + o.tick(o); + + // get attachment + o.spy(o, "value", "0123456789", "Get attachment"); + o.jio.get("file/attmt", o.f); + o.tick(o); + + // remove document + o.spy(o, "value", {"ok": true, "id": "file"}, "Remove document"); + o.jio.remove({"_id": "file"}, o.f); + o.tick(o); + + // remove attachment + o.spy(o, "value", {"ok": true, "id": "file/attmt"}, "Remove attachment"); + o.jio.remove({"_id": "file/attmt"}, o.f); + o.tick(o); + o.jio.stop(); }); -test ('Simple Job Replacement', function () { - // Test if the second job write over the first one +module ( "Jio Job Managing" ); - var o = {}; - o.clock = this.sandbox.useFakeTimers(); - o.clock.tick(base_tick); - o.id = 0; - o.f1 = function (err,val) { - if (err) { - o.err = err; - } else { - o.err = {status:'done'}; - } - }; - this.spy(o,'f1'); - o.f2 = this.spy(); - - o.jio = JIO.newJio({type:'dummyallok',applicationname:'jiotests'}); - o.id = o.jio.getId(); - o.jio.put({_id:'file',content:'content'},o.f1); - o.clock.tick(10); - o.jio.put({_id:'file',content:'content'},o.f2); - deepEqual(LocalOrCookieStorage.getItem( - 'jio/job_array/'+o.id)[0].date,base_tick + 10, - 'The first job date have to be equal to the second job date.'); - o.clock.tick(1000); - deepEqual([o.f1.calledOnce,o.err.status],[true,12], - 'callback for the first save request -> result fail'); - ok(o.f2.calledOnce,'second callback is called once'); +test ("Several Jobs at the same time", function () { + + var o = generateTools(this); + + o.jio = JIO.newJio({"type":"dummyallok"}); + o.spy(o, "value", {"ok": true, "id": "file"}, "job1", "f"); + o.spy(o, "value", {"ok": true, "id": "file2"}, "job2", "f2"); + o.spy(o, "value", {"ok": true, "id": "file3"}, "job3", "f3"); + o.jio.put({"_id": "file", "content": "content"}, o.f); + o.jio.put({"_id": "file2", "content": "content2"}, o.f2); + o.jio.put({"_id": "file3", "content": "content3"}, o.f3); + o.tick(o, 1000, "f"); + o.tick(o, "f2"); + o.tick(o, "f3"); o.jio.stop(); - o.jio = JIO.newJio({type:'dummyallok',applicationname:'jiotests'}); - o.ok1 = 0; - o.jio.get('file1',function (err,val) { - deepEqual (err || val, - {_id:'file1',content:'content', - _creation_date:10000,_last_modified:15000}, - 'First load'); - o.ok1 ++; - }); - o.ok2 = 0; - o.jio.get('file2',function (err,val) { - deepEqual (err || val, - {_id:'file2',content:'content', - _creation_date:10000,_last_modified:15000}, - 'Second load must not replace the first one'); - o.ok2 ++; - }); - o.clock.tick(1000); - if (o.ok1 !== 1) { - ok (false,'no response / too much response'); - } - if (o.ok2 !== 1) { - ok (false,'no response / too much response'); - } +}); + +test ("Similar Jobs at the same time (Replace)", function () { + + var o = generateTools(this); + + o.jio = JIO.newJio({"type":"dummyallok"}); + o.spy(o, "status", 12, "job1 replaced", "f"); + o.spy(o, "status", 12, "job2 replaced", "f2"); + o.spy(o, "value", {"ok": true, "id": "file"}, "job3 ok", "f3"); + o.jio.put({"_id": "file", "content": "content"}, o.f); + o.jio.put({"_id": "file", "content": "content"}, o.f2); + o.jio.put({"_id": "file", "content": "content"}, o.f3); + o.tick(o, 1000, "f"); + o.tick(o, "f2"); + o.tick(o, "f3"); o.jio.stop(); + }); -test ('Simple Job Waiting', function () { - // Test if the second job doesn't erase the first on going one +test ("One document aim jobs at the same time (Wait for job(s))" , function () { - var o = {}; - o.clock = this.sandbox.useFakeTimers(); - o.clock.tick(base_tick); - o.id = 0; - o.f = function (err,val) { - deepEqual(err || val,{ok:true,id:'file'},'job 1 result'); - }; - o.f3 = o.f; this.spy(o,'f3'); - o.f4 = o.f; this.spy(o,'f4'); - o.checkCallback = function (fun_name,message) { - if (!o[fun_name].calledOnce) { - if (o[fun_name].called) { - ok(false, 'too much response'); - } else { - ok(false, 'no response'); - } - } else { - ok(true,message); - } - }; + var o = generateTools(this); - o.jio = JIO.newJio({type:'dummyallok',applicationname:'jiotests'}); - o.id = o.jio.getId(); - o.jio.put({_id:'file',content:'content'},o.f3); - o.clock.tick(200); - o.jio.put({_id:'file',content:'content1'},o.f4); + o.jio = JIO.newJio({"type":"dummyallok"}); + o.spy(o, "value", {"ok": true, "id": "file"}, "job1", "f"); + o.spy(o, "value", {"ok": true, "id": "file"}, "job2", "f2"); + o.spy(o, "value", {"_id": "file", "title": "get_title"}, "job3", "f3"); - o.tmp0 = LocalOrCookieStorage.getItem('jio/job_array/'+o.id)[0]; - o.tmp1 = LocalOrCookieStorage.getItem('jio/job_array/'+o.id)[1]; + o.jio.post({"_id": "file", "content": "content"}, o.f); + o.testLastJobWaitForJob(undefined, "job1 is not waiting for someone"); - ok(o.tmp0 && o.tmp0.id === 1,'job 1 exists'); - deepEqual(o.tmp0.status.label,'on going','job 1 is on going'); - ok(o.tmp1 && o.tmp1.id === 2,'job 2 exists'); - deepEqual(o.tmp1.status.label,'wait','job 2 waiting'); - deepEqual(o.tmp1.status.waitforjob,[1], - 'job 2 must wait for the first to end'); + o.jio.put({"_id": "file", "content": "content"}, o.f2); + o.testLastJobWaitForJob([1], "job2 is waiting"); - o.clock.tick(1000); - o.checkCallback('f3','first request passed'); - o.checkCallback('f4','restore waiting job'); + o.jio.get("file", o.f3); + o.testLastJobWaitForJob([1, 2], "job3 is waiting"); + o.tick(o, 1000, "f"); + o.tick(o, "f2"); + o.tick(o, "f3"); o.jio.stop(); + }); -test ('Simple Time Waiting' , function () { - // Test if the job that have fail wait until a certain moment to restart. - // It will use the dummyall3tries, which will work after the 3rd try. +test ("One document aim jobs at the same time (Elimination)" , function () { - var o = {}, clock = this.sandbox.useFakeTimers(), id = 0; - clock.tick(base_tick); - o.f = function (err,val) { - if (err) { - o.res = err; - } else { - o.res = val; - } - }; - this.spy(o,'f'); - o.jio = JIO.newJio({type:'dummyall3tries',applicationname:'jiotests'}); - o.jio.put({_id:'file',content:'content'},{max_retry:3},o.f); - clock.tick(10000); - if (!o.f.calledOnce) { - if (o.f.called) { - ok(false,'callback called too much times.'); - } else { - ok(false,'no response.'); - } - } - deepEqual(o.res,{ok:true,id:'file'},'job done.'); + var o = generateTools(this); + + o.jio = JIO.newJio({"type":"dummyallok"}); + o.spy(o, "status", 10, "job1 stopped", "f"); + o.spy(o, "value", {"ok": true, "id": "file"}, "job2", "f2"); + + o.jio.post({"_id": "file", "content": "content"}, o.f); + o.testLastJobLabel("post", "job1 exists"); + + o.jio.remove({"_id": "file"}, o.f2); + o.testLastJobLabel("remove", "job1 does not exist anymore"); + + o.tick(o, 1000, "f"); + o.tick(o, "f2"); o.jio.stop(); + }); -module ( 'Jio Restore'); +test ("One document aim jobs at the same time (Not Acceptable)" , function () { -test ('Restore old Jio', function() { - var o = {}; - o.clock = this.sandbox.useFakeTimers(); - o.f = function() { - ok(false,'must never be called!'); - }; - this.spy(o,'f'); - o.jio = JIO.newJio({type:'dummyall3tries',applicationname:'jiotests'}); - o.id = o.jio.getId(); - ok(true,'create jio, id = ' + o.id); - o.jio.put({_id:'file',content:'content'},{max_retry:3},o.f); - o.clock.tick(1000); - o.jio.close(); - o.jio = JIO.newJio({type:'dummyallok',applicationname:'jiotests'}); - o.clock.tick(11000); // 10 sec - deepEqual(LocalOrCookieStorage.getItem('jio/job_array/'+o.id),null, - 'job array list must be empty'); - o.tmp1 = LocalOrCookieStorage.getItem('jio/job_array/'+o.jio.getId()); - if (o.tmp1.length > 0) { - deepEqual([o.tmp1[0].command.label,o.tmp1[0].command.doc._id, - o.tmp1[0].command.doc.content], - ['put','file','content'], - 'job which id is id = ' +o.jio.getId()+', restored the jio'); - } else { - ok (false, 'The recovered job must exists'); - } + var o = generateTools(this); + + o.jio = JIO.newJio({"type":"dummyallok"}); + o.spy(o, "value", {"_id": "file", "title": "get_title"}, "job1", "f"); + o.spy(o, "status", 11, "job2 is not acceptable", "f2"); + + o.jio.get("file", o.f); + o.testLastJobId(1, "job1 added to queue"); + o.waitUntilLastJobIs("on going"); + + o.jio.get("file", o.f2); + o.testLastJobId(1, "job2 not added"); + + o.tick(o, 1000, "f"); + o.tick(o, "f2"); o.jio.stop(); + }); -*/ +test ("Server will be available soon (Wait for time)" , function () { -module ( 'Jio LocalStorage' ); + var o = generateTools(this); + o.max_retry = 3; -// ============================== POST ========================== -test ('Post', function(){ + o.jio = JIO.newJio({"type":"dummyall3tries"}); + o.spy(o, "value", {"ok": true, "id": "file"}, "job1", "f"); - // runs following assertions - // 1) POST with id - should be an error - // 2) POST with attachment - should be an error - // 3) POST CREATE with content - // 4) check that document is created with UUID.revision - // 5) check that document revision tree is created - // 6) POST UPDATE + o.jio.put({"_id": "file", "content": "content"}, + {"max_retry": o.max_retry}, o.f); + for (o.i = 0; o.i < o.max_retry - 1; o.i += 1) { + o.waitUntilLastJobIs("on going"); + o.waitUntilLastJobIs("wait"); + o.testLastJobWaitForTime("job1 is waiting for time"); + } - var o = {}; - o.t = this; - o.clock = o.t.sandbox.useFakeTimers(), - localstorage = { - getItem: function (item) { - return JSON.parse (localStorage.getItem(item)); - }, - setItem: function (item,value) { - return localStorage.setItem(item,JSON.stringify(value)); - }, - deleteItem: function (item) { - delete localStorage[item]; - } - }; + o.tick(o, 1000, "f"); + o.jio.stop(); - o.clock.tick(base_tick); - o.spy = basic_spy_function; - o.clean = clean_up_local_storage_function(); - o.username = 'MrPost'; - o.testRevisionStorage = []; - - // let's go - o.jio = JIO.newJio({ type:'local', username:o.username, - applicationname:'jiotests' }); - // ======================================== - // 1) POST with id - o.jio.post({"_id":'file',"content":'content'},function(err, response){ - o.spy (o,'value',{ - "error": 'forbidden', - "message": 'Forbidden', - "reason": 'ID cannot be supplied with a POST request. Please use PUT', - "status": 403, - "statusText": 'Forbidden' - },'POST with id = 403 forbidden'); - o.f(err); +}); + +module ( "Jio Restore"); + +test ("Restore old Jio", function() { + + var o = generateTools(this); + + o.jio = JIO.newJio({ + "type": "dummyall3tries", + "applicationname": "jiotests" }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 2) POST attachment - o.jio.post({"_id":'file/ABC', "mimetype":'text/html', - "content":'<b>hello</b>'},function(err, response){ - o.spy (o,'value',{ - "error": 'forbidden', - "message": 'Forbidden', - "reason": 'Attachment cannot be added with a POST request', - "status": 403, - "statusText": 'Forbidden' - },'POST attachment = 403 forbidden'); - o.f(err); + + o.jio_id = o.jio.getId(); + + o.jio.put({"_id": "file", "title": "myFile"}, {"max_retry":3}, o.f); + o.waitUntilLastJobIs("on going"); + o.jio.close(); + + o.jio = JIO.newJio({ + "type": "dummyallok", + "applicationname": "jiotests" }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 3) POST content - o.jio.post({"content":'content'}, - function(err, response) { - o.spy(o,'value',{"ok":true,"id":response.id,"rev":response.rev}, - 'POST content = ok'); - o.f(response); - - // store falseRevision - o.falseRevision = response.rev; - - // build tree manually - o.testRevisionStorage.push(response.rev); - o.buildTestTree = {"kids":[],"rev":o.testRevisionStorage[0], - "status":'available',"type":'leaf'}; - - // 4) check if document is created and correct - checkFile(response, o, null, true); - // 5) check if document tree is created and correct - checkTreeNode(response, o, null, true); - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // END POST + o.waitUntilAJobExists(30000); // timeout 30 sec + o.testLastJobLabel("put", "Job restored"); + o.clock.tick(1000); + ok(getLastJob(o.jio.getId()) === undefined, + "Job executed"); + o.jio.stop(); - o.clean; + }); -// ============================== PUT ========================== - -test ('Put', function(){ - - // runs following assertions - // 1) PUT without ID = 409 - // 2) PUT with wrong ID/rev = 404 - // 3) PUT CREATE response - // 4) check file was created - // 5) check tree was created - // 6) PUT UPDATE response - // 7) check file was replaced - // 8) check tree was updated - // 9) PUT UPDATE 2 response - // 10) check file was replaced - // 11) check tree was updated - // 12) PUT UPDATE false revision = 409 - // 13) SYNC-PUT no revs_info = 409 - // 14) SYNC-PUT revs_info response - // 15) check if file created - // 16) check if tree was merged - // 17) SYNC-PUT revs_info dead leaf response - // 18) check that file was NOT created - // 19) check that tree was updated - - var fake_rev_0, - fake_rev_1, - fake_rev_2, - fake_id_0, - fake_id_1, - fake_id_2, - - o = {}; - o.t = this; - o.clock = o.t.sandbox.useFakeTimers(); - o.falseRevision; - localstorage = { - getItem: function (item) { - return JSON.parse (localStorage.getItem(item)); - }, - setItem: function (item,value) { - return localStorage.setItem(item,JSON.stringify (value)); - }, - deleteItem: function (item) { - delete localStorage[item]; - } - }; +module ( "Jio LocalStorage" ); - o.clock.tick(base_tick); - o.spy = basic_spy_function; - o.clean = clean_up_local_storage_function(); - o.username = 'MrPutt'; - o.testRevisionStorage = []; - - // let's go - o.jio = JIO.newJio({ type:'local', username:o.username, - applicationname:'jiotests' }); - // ======================================== - // 1) PUT without ID - o.jio.put({"content":'content'},function(err, response){ - - o.spy (o,'value',{ - "error": 'conflict', - "message": 'Document update conflict.', - "reason": 'Missing Document ID and or Revision', - "status": 409, - "statusText": 'Conflict' - },'PUT without id = 409 Conflict'); - o.f(err); - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 2) PUT wrong id/rev - o.jio.put({"content":'content', "_id":'myDoc', - "_rev":'1-ABCDEFG'}, function(err, response){ - o.spy (o,'value',{ - "error": 'not found', - "message": 'Document not found.', - "reason": 'Document not found, please check revision and/or ID', - "status": 404, - "statusText": 'Not found' - },'PUT with wrong id/revision = 404 Not found'); - o.f(err); - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 3) PUT content - o.jio.put({"content":'content',"_id":'myDoc'}, - function(err, response) { - - o.spy(o,'value',{"ok":true,"id":response.id,"rev":response.rev}, - 'PUT content = ok'); - o.f(response); - - o.falseRevision = response.rev; - o.testRevisionStorage.unshift(response.rev); - o.buildTestTree = {"kids":[],"rev":o.testRevisionStorage[0], - "status":'available',"type":'leaf'}; - // ======================================== - // 4) check file was created - checkFile(response, o, null, true); - // ======================================== - // 5) check tree was created - checkTreeNode(response, o, null, true); - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 6) PUT UPDATE (modify content) - o.jio.put({"content":'content_modified',"_id":'myDoc', - "_rev":o.testRevisionStorage[0]}, - function(err, response) { - o.spy(o,'value',{"ok":true,"id":response.id,"rev":response.rev}, - 'PUT content = ok'); - o.f(response); - - o.testRevisionStorage.unshift(response.rev); - o.buildTestTree = {"kids":[{"kids":[],"rev": - o.testRevisionStorage[0],"status":'available', - "type":'leaf'}],"rev":o.testRevisionStorage[1], - "status":'deleted',"type":'branch'}; - // ======================================== - // 7) check document was replaced - checkFile(response, o, null, true); - // ======================================== - // 8) check tree was updated - checkTreeNode(response, o, null, true); - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 9. update document (modify again) - o.jio.put({"content":'content_modified_again', - "_id":'myDoc', "_rev":o.testRevisionStorage[0]}, - function(err, response) { - o.spy(o,'value',{"ok":true,"id":response.id, - "rev":response.rev}, 'PUT content = ok'); - o.f(response); - - o.testRevisionStorage.unshift(response.rev); - o.buildTestTree = {"kids":[{"kids":[{"kids":[], - "rev":o.testRevisionStorage[0],"status":'available', - "type":'leaf'}],"rev":o.testRevisionStorage[1], - "status":'deleted',"type":'branch'}], - "rev":o.testRevisionStorage[2],"status":'deleted', - "type":'branch'}; - - // 10) check document was replaced - checkFile(response, o, null, true); - // 11) check tree was updated - checkTreeNode(response, o, null, true); +test ("Post", function(){ - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 12) PUT false revision - o.jio.put({"content":'content_modified_false', - "_id":'myDoc', - "_rev":o.falseRevision},function(err, response){ - o.spy (o,'value',{ - "error": 'conflict', - "message": 'Document update conflict.', - "reason": - 'Revision supplied is not the latest revision', - "status": 409, - "statusText": 'Conflict' - },'PUT false revision = 409 Conflict'); - o.f(err); + var o = generateTools(this); + + o.jio = JIO.newJio({ + "type": "local", + "username": "upost", + "applicationname": "apost" }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 13) SYNC-PUT no revs_info - o.jio.put({"content":'content_modified_false', - "_id":'myDoc', - "_rev":'1-abcdefg'},function(err, response){ - o.spy (o,'value',{ - "error": 'conflict', - "message": 'Document update conflict.', - "reason": - 'Missing revs_info required for sync-put', - "status": 409, - "statusText": 'Conflict' - },'PUT no sync info = 409 Conflict'); - o.f(err); + + // post without id + o.spy (o, "status", 405, "Post without id"); + o.jio.post({}, o.f); + o.tick(o); + + // post non empty document + o.spy (o, "value", {"ok": true, "id": "post1"}, "Post"); + o.jio.post({"_id": "post1", "title": "myPost1"}, o.f); + o.tick(o); + + deepEqual( + localstorage.getItem("jio/localstorage/upost/apost/post1"), + { + "_id": "post1", + "title": "myPost1" + }, + "Check document" + ); + + // post but document already exists + o.spy (o, "status", 409, "Post but document already exists"); + o.jio.post({"_id": "post1", "title": "myPost2"}, o.f); + o.tick(o); + + o.jio.stop(); +}); + + +test ("Put", function(){ + + var o = generateTools(this); + + o.jio = JIO.newJio({ + "type": "local", + "username": "uput", + "applicationname": "aput" }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // add a new document version with fake revs_info - // the new document has the same origin and first edit, - // then it was changed to a new version (3-a9d...), - // which was changed to a fourth version (4-b5bb...), - // the tree must merge on o.testRevisionStorage[1] - // and add the two new dummy revisions into the final - // tree. Also the new document should be stored - // in local storage. - fake_rev_2 = o.testRevisionStorage[2]; - fake_rev_1 = o.testRevisionStorage[1]; - fake_rev_0 = o.testRevisionStorage[0]; - fake_id_2 = o.testRevisionStorage[2].split('-')[1]; - fake_id_1 = o.testRevisionStorage[1].split('-')[1]; - fake_id_0 = o.testRevisionStorage[0].split('-')[1]; - // ======================================== - // 14) PUT UPDATE A TREE using revs_info - o.jio.put({ - "content":'a_new_version', - "_id":'myDoc', - "_rev":"4-b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89", - "_revs_info":[ - {"rev":"4-b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89","status":"available"}, - {"rev":"3-a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123","status":"deleted"}, - {"rev":fake_rev_1,"status":"deleted"}, - {"rev":fake_rev_0,"status":"deleted"} - ], - "_revisions":{ - "start":4, - "ids":[ - "b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89", - "a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123", - fake_id_1, - fake_id_0 - ]} + // put without id + o.spy (o, "status", 20, "Put without id"); + o.jio.put({}, o.f); + o.tick(o); + + // put non empty document + o.spy (o, "value", {"ok": true, "id": "put1"}, "Creates a document"); + o.jio.put({"_id": "put1", "title": "myPut1"}, o.f); + o.tick(o); + + // check document + deepEqual( + localstorage.getItem("jio/localstorage/uput/aput/put1"), + { + "_id": "put1", + "title": "myPut1" }, - function(err, response) { - o.buildTestTree = { - "kids":[ - { - "kids":[ - {"kids":[],"rev":o.testRevisionStorage[0],"status":'available',"type":'leaf'}, - {"kids":[{ - "kids":[], - "rev":"4-b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89", - "status":'available', "type":'leaf' - }], - "rev":"3-a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123", - "status":'deleted',"type":'branch' - }], - "rev":o.testRevisionStorage[1],"status":'deleted',"type":'branch'}], - "rev":o.testRevisionStorage[2],"status":'deleted',"type":'branch' - }; - o.spy(o,'value',{"ok":true,"id":response.id, - "rev":response.rev}, 'PUT SYNC = ok'); - o.f(response); - // 15) check document was stored - checkFile(response, o, null, true); - // 16) check tree was updated - checkTreeNode(response, o, null, true); - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // ======================================== - // 17) PUT UPDATE (deleted tree) - o.jio.put({ - "content":'a_deleted_version', - "_id":'myDoc', - "_rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61", - "_revs_info":[ - {"rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61","status":"deleted"}, - {"rev":"2-67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844","status":"deleted"}, - {"rev":fake_rev_2,"status":"deleted"} - ], - "_revisions":{ - "start":3, - "ids":[ - "05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61", - "67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844", - fake_id_2 - ]} + "Check document" + ); + + // put but document already exists + o.spy (o, "value", {"ok": true, "id": "put1"}, "Update the document"); + o.jio.put({"_id": "put1", "title": "myPut2"}, o.f); + o.tick(o); + + // check document + deepEqual( + localstorage.getItem("jio/localstorage/uput/aput/put1"), + { + "_id": "put1", + "title": "myPut2" }, - function(err, response) { - - o.buildTestTree = { - "kids":[{ - "kids":[ - {"kids":[], - "rev":o.testRevisionStorage[0], - "status":'available', - "type":'leaf' - }, - {"kids":[{ - "kids":[], - "rev":"4-b5bb2f1657ac5ac270c14b2335e51ef1ffccc0a7259e14bce46380d6c446eb89", - "status":'available', "type":'leaf' - }], - "rev":"3-a9dac9ff5c8e1b2fce58e5397e9b6a8de729d5c6eff8f26a7b71df6348986123", - "status":'deleted', - "type":'branch' - }], - "rev":o.testRevisionStorage[1], - "status":'deleted', - "type":'branch' - },{ - "kids":[ - { - "kids":[], - "rev":"3-05210795b6aa8cb5e1e7f021960d233cf963f1052b1a41777ca1a2aff8fd4b61", - "status":'deleted', - "type":'leaf' - }], - "rev":"2-67ac10df5b7e2582f2ea2344b01c68d461f44b98fef2c5cba5073cc3bdb5a844", - "status":'deleted', - "typ":'branch' - }], - "rev":o.testRevisionStorage[2], - "status":'deleted', - "type":'branch' - }; - o.spy(o,'value',{"ok":true,"id":response.id, - "rev":response.rev}, 'PUT SYNC dead leaf = ok'); - o.f(response); - // 18) check document was stored - checkFile(response, o, null, true); - // 19) check tree was updated - checkTreeNode(response, o, null, true); - }); - checkReply(o,null,true); - o.clock.tick(base_tick); - // END PUT + "Check document" + ); + o.jio.stop(); - o.clean; + }); +test ("PutAttachment", function(){ -// ====================== PUTATTACHMENT ========================== -test ('PutAttachment', function(){ - - // runs following assertions - // 1) PUTATTACHMENT with wrong id/rev1 - // 2) PUTATTACHMENT without id/rev1 - - var o = {}; - o.t = this; - o.clock = o.t.sandbox.useFakeTimers(); - o.falseRevision; - localstorage = { - getItem: function (item) { - return JSON.parse (localStorage.getItem(item)); - }, - setItem: function (item,value) { - return localStorage.setItem(item,JSON.stringify (value)); - }, - deleteItem: function (item) { - delete localStorage[item]; - } - }; + var o = generateTools(this); - o.clock.tick(base_tick); - o.spy = basic_spy_function; - o.clean = clean_up_local_storage_function(); - o.username = 'MrPuttAttachment'; - o.testRevisionStorage = []; - - // let's go - o.jio = JIO.newJio({ type:'local', username:o.username, - applicationname:'jiotests' }); - // ======================================== - // 1) PUTATTACHMENT with wrong id/rev - o.jio.putAttachment("ABC/DEF","A-1aaa","<b>hello</b>","text/html",function(err, response){ - o.spy (o,'value',{ - "error": 'not found', - "message": 'Document not found.', - "reason": 'Document not found, please check document ID', - "status": 404, - "statusText": 'Not found' - },'PUTATTACHMENT without id = 404 NOT FOUND'); - o.f(err); + o.jio = JIO.newJio({ + "type": "local", + "username": "uputattmt", + "applicationname": "aputattmt" }); - checkReply(o,null,true); - // ======================================== - // 2) PUTATTACHMENT with wrong id/rev - /* - o.jio.putAttachment("ABC/DEF","text/html","<b>hello</b>",function(err, response){ - o.spy (o,'value',{ - "error": 'not found', - "message": 'Document not found.', - "reason": 'Document not found, please check document ID', - "status": 404, - "statusText": 'Not found' - },'PUTATTACHMENT without id = 404 NOT FOUND'); - o.f(err); + + // putAttachment without doc id + // error 20 -> document id required + o.spy(o, "status", 20, "PutAttachment without doc id"); + o.jio.putAttachment({}, o.f); + o.tick(o); + + // putAttachment without attmt id + // error 22 -> attachment id required + o.spy(o, "status", 22, "PutAttachment without attmt id"); + o.jio.putAttachment({"id": "putattmt1"}, o.f); + o.tick(o); + + // putAttachment without document + // error 404 -> not found + o.spy(o, "status", 404, "PutAttachment without document"); + o.jio.putAttachment({"id": "putattmt1/putattmt2"}, o.f); + o.tick(o); + + // adding a document + localstorage.setItem("jio/localstorage/uputattmt/aputattmt/putattmt1", { + "_id": "putattmt1", + "title": "myPutAttmt1" }); - checkReply(o,null,true); - */ + + // putAttachment with document + o.spy(o, "value", {"ok": true, "id": "putattmt1/putattmt2"}, + "PutAttachment with document, without data"); + o.jio.putAttachment({"id": "putattmt1/putattmt2"}, o.f); + o.tick(o); + + // check document + deepEqual( + localstorage.getItem("jio/localstorage/uputattmt/aputattmt/putattmt1"), + { + "_id": "putattmt1", + "title": "myPutAttmt1", + "_attachments": { + "putattmt2": { + "length": 0, + // md5("") + "digest": "md5-d41d8cd98f00b204e9800998ecf8427e" + } + } + }, + "Check document" + ); + + // check attachment + deepEqual( + localstorage.getItem( + "jio/localstorage/uputattmt/aputattmt/putattmt1/putattmt2"), + "", "Check attachment" + ); + + // update attachment + o.spy(o, "value", {"ok": true, "id": "putattmt1/putattmt2"}, + "Update Attachment, with data"); + o.jio.putAttachment({"id": "putattmt1/putattmt2", "data": "abc"}, o.f); + o.tick(o); + + // check document + deepEqual( + localstorage.getItem("jio/localstorage/uputattmt/aputattmt/putattmt1"), + { + "_id": "putattmt1", + "title": "myPutAttmt1", + "_attachments": { + "putattmt2": { + "length": 3, + // md5("abc") + "digest": "md5-900150983cd24fb0d6963f7d28e17f72" + } + } + }, + "Check document" + ); + + // check attachment + deepEqual( + localstorage.getItem( + "jio/localstorage/uputattmt/aputattmt/putattmt1/putattmt2"), + "abc", "Check attachment" + ); + + o.jio.stop(); }); -/* -test ('Document load', function () { - // Test if LocalStorage can load documents. - // We launch a loading from localstorage and we check if the file is - // realy loaded. +test ("Get", function(){ - var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this; - o.clock.tick(base_tick); - o.spy = basic_spy_function; - o.tick = basic_tick_function; + var o = generateTools(this); - o.jio = JIO.newJio({type:'local',username:'MrLoadName', - applicationname:'jiotests'}); - // save and check document existence - o.doc = {_id:'file',content:'content', - _last_modified:1234,_creation_date:1000}; + o.jio = JIO.newJio({ + "type": "local", + "username": "uget", + "applicationname": "aget" + }); + + // get unexistant document + o.spy(o, "status", 404, "Get unexistant document"); + o.jio.get("get1", o.f); + o.tick(o); + + // get unexistant attachment + o.spy(o, "status", 404, "Get unexistant attachment"); + o.jio.get("get1/get2", o.f); + o.tick(o); + + // adding a document + o.doc_get1 = { + "_id": "get1", + "title": "myGet1" + }; + localstorage.setItem("jio/localstorage/uget/aget/get1", o.doc_get1); + + // get document + o.spy(o, "value", o.doc_get1, "Get document"); + o.jio.get("get1", o.f); + o.tick(o); - o.spy(o,'status',404,'loading document failure'); - o.jio.get('file',o.f); + // get unexistant attachment (document exists) + o.spy(o, "status", 404, "Get unexistant attachment (document exists)"); + o.jio.get("get1/get2", o.f); o.tick(o); - addFileToLocalStorage('MrLoadName','jiotests',o.doc); - o.spy(o,'value',o.doc,'loading document success'); - o.jio.get('file',o.f); + // adding an attachment + o.doc_get1["_attachments"] = { + "get2": { + "length": 2, + // md5("de") + "digest": "md5-5f02f0889301fd7be1ac972c11bf3e7d" + } + }; + localstorage.setItem("jio/localstorage/uget/aget/get1", o.doc_get1); + localstorage.setItem("jio/localstorage/uget/aget/get1/get2", "de"); + + // get attachment + o.spy(o, "value", "de", "Get attachment"); + o.jio.get("get1/get2", o.f); o.tick(o); o.jio.stop(); + }); -*//* -test ('Get document list', function () { - // Test if LocalStorage can get a list of documents. - // We create 2 documents inside localStorage to check them. - var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this; - o.clock.tick(base_tick); - o.mytest = function (value){ - o.f = function (err,val) { - if (val) { - deepEqual (objectifyDocumentArray(val.rows), - objectifyDocumentArray(value),'getting list'); - } else { - deepEqual (err,value,'getting list'); - } - }; - o.t.spy(o,'f'); - o.jio.allDocs(o.f); - o.clock.tick(1000); - if (!o.f.calledOnce) { - if (o.f.called) { - ok(false, 'too much results'); - } else { - ok(false, 'no response'); +test ("Remove", function(){ + + var o = generateTools(this); + + o.jio = JIO.newJio({ + "type": "local", + "username": "uremove", + "applicationname": "aremove" + }); + + // remove unexistant document + o.spy(o, "status", 404, "Remove unexistant document"); + o.jio.remove({"_id": "remove1"}, o.f); + o.tick(o); + + // remove unexistant document/attachment + o.spy(o, "status", 404, "Remove unexistant document/attachment"); + o.jio.remove({"_id": "remove1/remove2"}, o.f); + o.tick(o); + + // adding a document + localstorage.setItem("jio/localstorage/uremove/aremove/remove1", { + "_id": "remove1", + "title": "myRemove1" + }); + + // remove document + o.spy(o, "value", {"ok": true, "id": "remove1"}, "Remove document"); + o.jio.remove({"_id": "remove1"}, o.f); + o.tick(o); + + // check document + ok(localstorage.getItem("jio/localstorage/uremove/aremove/remove1")===null, + "Check documuent"); + + // adding a document + attmt + localstorage.setItem("jio/localstorage/uremove/aremove/remove1", { + "_id": "remove1", + "title": "myRemove1", + "_attachments": { + "remove2": { + "length": 4, + "digest": "md5-blahblah" } } - }; - o.jio = JIO.newJio({type:'local',username:'MrListName', - applicationname:'jiotests'}); - o.doc1 = {_id:'file',content:'content', - _last_modified:1,_creation_date:0}; - o.doc2 = {_id:'memo',content:'test', - _last_modified:5,_creation_date:2}; - addFileToLocalStorage ('MrListName','jiotests',o.doc1); - addFileToLocalStorage ('MrListName','jiotests',o.doc2); - o.mytest ([{ - id:o.doc2._id,key:o.doc2._id, - value:{ - _creation_date:o.doc2._creation_date, - _last_modified:o.doc2._last_modified - } - },{ - id:o.doc1._id,key:o.doc1._id, - value:{ - _last_modified:o.doc1._last_modified, - _creation_date:o.doc1._creation_date - } - }]); + }); + localstorage.setItem( + "jio/localstorage/uremove/aremove/remove1/remove2", "fghi"); + + // remove attachment + o.spy(o, "value", {"ok": true, "id": "remove1"}, "Remove attachment"); + o.jio.remove({"_id": "remove1"}, o.f); + o.tick(o); o.jio.stop(); + }); -*//* -test ('Document remove', function () { - // Test if LocalStorage can remove documents. - // We launch a remove from localstorage and we check if the file is - // realy removed. - var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this; - o.clock.tick(base_tick); - o.spy = basic_spy_function; - o.tick = function () { - basic_tick_function.apply(basic_tick_function,arguments); - // check if the file is still there - o.tmp = LocalOrCookieStorage.getItem ( - 'jio/local/MrRemoveName/jiotests/file'); - ok (!o.tmp, 'check no content'); - }; - o.jio = JIO.newJio({type:'local',username:'MrRemoveName', - applicationname:'jiotests'}); - // test removing a file - o.spy (o,'value',{ok:true,id:'file'},'removing document'); - addFileToLocalStorage ('MrRemoveName','jiotests',{_id:'file'}); - o.jio.remove({_id:'file'},o.f); - o.tick (o); +test ("AllDocs", function(){ + + var o = generateTools(this); + + o.jio = JIO.newJio({ + "type": "local", + "username": "ualldocs", + "applicationname": "aalldocs" + }); + + // alldocs + // error 405 -> method not allowed + o.spy(o, "status", 405, "Method not allowed"); + o.jio.allDocs(o.f); + o.tick(o); o.jio.stop(); + }); -*/ + /* module ('Jio DAVStorage'); @@ -2818,7 +2598,6 @@ if (window.requirejs) { paths: { jiotestsloader: './jiotests.loader', - LocalOrCookieStorage: './testlocalorcookiestorage', jQueryAPI: '../lib/jquery/jquery', jQuery: '../js/jquery.requirejs_module', JIO: '../src/jio', @@ -2832,8 +2611,7 @@ if (window.requirejs) { }); require(['jiotestsloader'],thisfun); } else { - thisfun ({LocalOrCookieStorage:LocalOrCookieStorage, - JIO:jIO, + thisfun ({JIO:jIO, sjcl:sjcl, Base64:Base64, jQuery:jQuery}); diff --git a/test/jiotests_withoutrequirejs.html b/test/jiotests_withoutrequirejs.html index d85a57444127ab9efc51ecfa483d0bfbfc707e84..cdd444acaeb7cf8a411e93c9ef6d1860a056f6f8 100644 --- a/test/jiotests_withoutrequirejs.html +++ b/test/jiotests_withoutrequirejs.html @@ -11,8 +11,9 @@ <script type="text/javascript" src="../lib/sinon/sinon.js"></script> <script type="text/javascript" src="../lib/sinon/sinon-qunit.js"></script> <script type="text/javascript" src="../lib/jquery/jquery.min.js"></script> - <script type="text/javascript" src="./testlocalorcookiestorage.js"></script> + <script type="text/javascript" src="./browserlocalstorage.stub.js"></script> + <script type="text/javascript" src="../lib/md5/md5.js"></script> <script type="text/javascript" src="../jio.js"></script> <script type="text/javascript" src="../lib/base64/base64.js"></script>