Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Cédric Le Ninivin
jio
Commits
31e65d17
Commit
31e65d17
authored
Dec 14, 2012
by
Sven Franck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added revision management, POST working, PUT partially
parent
2c7d952d
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
808 additions
and
143 deletions
+808
-143
examples/complex_example.html
examples/complex_example.html
+1
-0
src/jio.dummystorages.js
src/jio.dummystorages.js
+39
-3
src/jio.storage/localstorage.js
src/jio.storage/localstorage.js
+472
-84
src/jio/commands/command.js
src/jio/commands/command.js
+7
-3
src/jio/commands/putAttachmentCommand.js
src/jio/commands/putAttachmentCommand.js
+1
-1
src/jio/jio.outro.js
src/jio/jio.outro.js
+8
-2
test/jiotests.js
test/jiotests.js
+280
-50
No files found.
examples/complex_example.html
View file @
31e65d17
...
...
@@ -238,6 +238,7 @@ var command = function (method) {
log
(
'
revision:
'
+
other
.
revision
);
log
(
'
content:
'
+
other
.
content
);
log
(
'
mimetype:
'
+
other
.
mimetype
);
break
;
case
'
post
'
:
case
'
put
'
:
doc
=
JSON
.
parse
(
$
(
'
#metadata
'
).
attr
(
'
value
'
));
...
...
src/jio.dummystorages.js
View file @
31e65d17
...
...
@@ -18,12 +18,47 @@
return
o
;
};
// Fake revisions
var
fakeCount
=
0
;
var
generateRevision
=
function
(
command
,
action
,
reset
){
var
that
=
{},
priv
=
{},
fakeRevision
=
""
,
fakeCount
=
reset
===
true
?
0
:
fakeCount
,
now
=
Date
.
now
();
that
.
makeHash
=
function
(){
return
that
.
hashCode
(
''
+
command
.
getDocId
()
+
'
'
+
now
+
''
);
};
that
.
hashCode
=
function
(
string
)
{
return
hex_sha256
(
string
);
};
that
.
generateNextRev
=
function
(
previous_revision
,
string
)
{
return
(
parseInt
(
previous_revision
.
split
(
'
-
'
)[
0
],
10
)
+
1
)
+
'
-
'
+
priv
.
hashCode
(
previous_revision
+
string
);
};
if
(
fakeRevision
===
""
&&
fakeCount
===
0
){
fakeRevision
=
'
1-
'
+
that
.
makeHash
();
}
else
{
if
(
action
!==
"
post
"
){
fakeRevision
=
that
.
generateNextRev
(
fakeRev
,
that
.
makeHash
);
}
}
return
fakeRevision
;
};
that
.
post
=
function
(
command
)
{
setTimeout
(
function
()
{
that
.
success
({
that
.
success
({
ok
:
true
,
id
:
command
.
getDocId
()
id
:
command
.
getDocId
(),
rev
:
generateRevision
(
command
,
"
post
"
,
true
)
});
},
100
);
};
// end post
...
...
@@ -32,7 +67,8 @@
setTimeout
(
function
()
{
that
.
success
({
ok
:
true
,
id
:
command
.
getDocId
()
id
:
command
.
getDocId
(),
rev
:
generateRevision
(
command
,
"
put
"
,
true
)
});
},
100
);
// 100 ms, for jiotests simple job waiting
};
// end put
...
...
src/jio.storage/localstorage.js
View file @
31e65d17
...
...
@@ -235,40 +235,63 @@ var newLocalStorage = function ( spec, my ) {
};
/**
* Create a document in the local storage.
* It will store the file in 'jio/local/USR/APP/FILE_NAME'.
* The command may have some options:
* - {boolean} conflicts Add a conflicts object to the response
* - {boolean} revs Add the revisions history of the document
* - {boolean} revs_info Add revisions informations
* @method post
* @method throwError - Creates the error object for all errors
*
* @param {code} string - the error code.
* @param {reason} string - the error reason
*/
that
.
post
=
function
(
command
)
{
var
now
=
Date
.
now
();
// wait a little in order to simulate asynchronous saving
setTimeout
(
function
()
{
var
docid
,
hash
,
doc
,
ret
,
path
;
priv
.
throwError
=
function
(
code
,
reason
)
{
var
statusText
,
error
,
message
,
e
;
if
(
command
.
getAttachmentId
())
{
that
.
error
({
status
:
403
,
statusText
:
'
Forbidden
'
,
error
:
'
forbidden
'
,
message
:
'
Cannot add an attachment with post request.
'
,
reason
:
'
attachment cannot be added with a post request
'
});
return
;
switch
(
code
){
case
409
:
statusText
=
'
Conflict
'
;
error
=
'
conflict
'
;
message
=
'
Document update conflict.
'
;
break
;
case
403
:
statusText
=
'
Forbidden
'
;
error
=
'
forbidden
'
;
message
=
'
Forbidden
'
;
break
;
case
404
:
statusText
=
'
Not found
'
;
error
=
'
not_found
'
;
message
=
'
Document not found.
'
;
break
;
}
docid
=
command
.
getDocId
();
path
=
'
jio/local/
'
+
priv
.
secured_username
+
'
/
'
+
priv
.
secured_applicationname
+
'
/
'
+
docid
;
// create object
e
=
({
status
:
code
,
statusText
:
statusText
,
error
:
error
,
message
:
message
,
reason
:
reason
});
return
e
;
};
// reading
doc
=
localstorage
.
getItem
(
path
);
if
(
!
doc
)
{
hash
=
priv
.
hashCode
(
''
+
doc
+
'
'
+
now
+
''
);
// create document
doc
=
{};
doc
.
_id
=
docid
;
/**
* @method createDocument - Creates a new document
*
* docid will be "" for POST and a string for PUT
*
* @param {docid} string - id for the new document
* @param {docpath} string - the path where to store the document
*
* @stored 'jio/local/USR/APP/FILE_NAME'
*/
priv
.
createDocument
=
function
(
docId
,
docPath
)
{
var
now
=
Date
.
now
(),
doc
=
{},
hash
=
priv
.
hashCode
(
''
+
doc
+
'
'
+
now
+
''
),
docPathRev
;
doc
.
_id
=
docId
;
doc
.
_rev
=
'
1-
'
+
hash
;
doc
.
_revisions
=
{
start
:
1
,
...
...
@@ -276,90 +299,400 @@ var newLocalStorage = function ( spec, my ) {
};
doc
.
_revs_info
=
[{
rev
:
'
1-
'
+
hash
,
// status can be 'available', 'deleted' or 'missing'
status
:
'
available
'
}];
// allow to store multiple versions of a document by including rev
docPathRev
=
docPath
+
'
/
'
+
doc
.
_rev
;
// store
localstorage
.
setItem
(
docPathRev
,
doc
);
return
doc
;
};
/**
* @method updateDocument - updates a document
*
* called from PUT or PUTATTACHMENT (or REMOVE?)
*
* @param {docid} string - id for the new document
* @param {docpath} string - the path where to store the document
* @param {prev_rev} string- the previous revision
*
*/
priv
.
updateDocument
=
function
(
doc
,
docPath
,
prev_rev
)
{
var
now
=
Date
.
now
(),
rev
=
priv
.
generateNextRev
(
prev_rev
,
''
+
doc
+
'
'
+
now
+
''
);
// update document
doc
.
_rev
=
rev
.
join
(
'
-
'
);
doc
.
_revisions
.
ids
.
unshift
(
rev
[
1
]);
doc
.
_revisions
.
start
=
rev
[
0
];
doc
.
_revs_info
[
0
].
status
=
'
deleted
'
;
doc
.
_revs_info
.
unshift
({
"
rev
"
:
rev
.
join
(
'
-
'
),
"
status
"
:
"
available
"
});
// store
localstorage
.
setItem
(
docPath
,
doc
);
return
doc
;
};
/**
* @method createDocumentTree - Creates a new document.tree
*
* @param {docId} string - id for the new document
* @param {doc } object - the document object
* @param {docPath} string - the path where to store the document
*
* the tree will include
* @key {type} string - branch or leaf
* @key {status} string - available or deleted
* @key {rev} string - revision string of this node
* @key {spawns} object - child branches/leaves
*
* @stored 'jio/local/USR/APP/FILE_NAME/TREE_revision'.
*
* the tree is maintained as long as more than one leaf exists(!)
* a leaf set to status "deleted" implies a deleted document version
* When all leaves have been set to "deleted", the tree is also deleted.
*
*/
priv
.
createDocumentTree
=
function
(
doc
,
docId
,
docPath
){
var
tree
=
{
type
:
'
leaf
'
,
status
:
'
available
'
,
rev
:
doc
.
_rev
,
kids
:{}
},
treePath
=
docPath
+
'
/revision_tree
'
;
// store
localstorage
.
setItem
(
treePath
,
tree
);
};
/**
* @method updateDocumentTree - update a document tree
*
* @param {docId} string - id for the new document
* @param {doc } object - the document object
* @param {docPath} string - the path where to store the document
*
* a tree can be grown (update a document) or split (when creating
* a new version). Growing the tree means changing a leaf into
* a branch and creating a new leaf. This is done here.
*
*/
priv
.
updateDocumentTree
=
function
(
){
};
/**
* @method getLastTreeRevision - find a leaf
*
* @param {docTree} string - the tree for this document
*
* this method should get the last leaf on the tree.
* If there are multiple leaves that come into question
* we select same as COUCHDB, highest rev counter, than
* compare ASCII. We will return only a single document
*
*/
priv
.
getLastTreeRevision
=
function
(
docTree
){
};
/**
* @method post
*
* Create a document in local storage.
*
* Available options:
* - {boolean} conflicts - Add a conflicts object to the response
* - {boolean} revs - Add the revisions history of the document
* - {boolean} revs_info - Add revisions informations
*
*/
that
.
post
=
function
(
command
)
{
setTimeout
(
function
()
{
var
docId
=
command
.
getDocId
(),
docPath
=
'
jio/local/
'
+
priv
.
secured_username
+
'
/
'
+
priv
.
secured_applicationname
+
'
/
'
+
docId
,
treePath
=
docPath
+
'
/revision_tree
'
,
docTree
=
localstorage
.
getItem
(
treePath
),
doc
=
localstorage
.
getItem
(
docPath
),
reg
;
// no attachments allowed
if
(
command
.
getAttachmentId
())
{
that
.
error
(
priv
.
throwError
(
403
,
'
Attachment cannot be added with a POST request
'
)
);
return
;
}
// check for UUID
reg
=
/^
[
0-9a-f
]{8}
-
[
0-9a-f
]{4}
-
[
0-9a-f
]{4}
-
[
0-9a-f
]{4}
-
[
0-9a-f
]{12}
$/i
.
test
(
docId
);
if
(
reg
!==
true
)
{
// id was supplied, use PUT
that
.
error
(
priv
.
throwError
(
403
,
'
ID cannot be supplied with a POST request. Please use PUT
'
)
);
return
;
}
else
{
// create and store new document
doc
=
priv
.
createDocument
(
docId
,
docPath
);
// create and store new document.tree
priv
.
createDocumentTree
(
doc
,
docId
,
docPath
);
// add user
if
(
!
priv
.
doesUserExist
(
priv
.
secured_username
))
{
priv
.
addUser
(
priv
.
secured_username
);
}
priv
.
addFileName
(
docid
);
}
else
{
// cannot overwrite
that
.
error
({
status
:
409
,
statusText
:
'
Conflict
'
,
error
:
'
conflict
'
,
message
:
'
Document already exists.
'
,
reason
:
'
the document already exists
'
// add fileName
priv
.
addFileName
(
docId
);
that
.
success
(
priv
.
manageOptions
(
{
ok
:
true
,
id
:
docId
,
rev
:
doc
.
_rev
},
command
,
doc
)
);
}
});
};
// end post
/**
* @method put
*
* Create or Update a document in local storage.
*
* Available options:
* - {boolean} conflicts - Add a conflicts object to the response
* - {boolean} revs - Add the revisions history of the document
* - {boolean} revs_info - Add revisions informations
*/
that
.
put
=
function
(
command
)
{
setTimeout
(
function
()
{
var
docId
=
command
.
getDocId
(),
prev_rev
=
command
.
getDocInfo
(
'
_rev
'
),
docPath
=
'
jio/local/
'
+
priv
.
secured_username
+
'
/
'
+
priv
.
secured_applicationname
+
'
/
'
+
docId
,
docPathRev
=
docPath
+
'
/
'
+
prev_rev
,
treePath
=
docPath
+
'
/revision_tree
'
,
docTree
=
localstorage
.
getItem
(
treePath
),
doc
,
reg
;
// no tree = create document or error
if
(
!
docTree
)
{
// check UUID
reg
=
/^
[
0-9a-f
]{8}
-
[
0-9a-f
]{4}
-
[
0-9a-f
]{4}
-
[
0-9a-f
]{4}
-
[
0-9a-f
]{12}
$/i
.
test
(
docId
);
// id/revision provided = update, revision must be incorrect
if
(
prev_rev
!==
undefined
&&
reg
===
false
){
that
.
error
(
priv
.
throwError
(
409
,
'
Incorrect Revision or ID
'
)
);
return
;
}
// revision provided = update, wrong revision or missing id
if
(
prev_rev
!==
undefined
){
that
.
error
(
priv
.
throwError
(
404
,
'
Document not found, please check revision and/or ID
'
)
);
return
;
}
// no revision and UUID = create, no id provided
if
(
prev_rev
===
undefined
&&
reg
===
true
){
that
.
error
(
priv
.
throwError
(
409
,
'
Missing Document ID and or Revision
'
)
);
return
;
}
localstorage
.
setItem
(
path
,
doc
);
// if passed here, we create.
// it could be create (id+content) or update (without revision)
// but since no tree was found and the tree includes id only
// we only end here with a NEW id, so update sans revision cannot
// be the case.
// create and store new document
doc
=
priv
.
createDocument
(
docId
,
docPath
);
// create and store new document.tree
priv
.
createDocumentTree
(
doc
,
docId
,
docPath
);
// add user
if
(
!
priv
.
doesUserExist
(
priv
.
secured_username
))
{
priv
.
addUser
(
priv
.
secured_username
);
}
// add fileName
priv
.
addFileName
(
docId
);
that
.
success
(
priv
.
manageOptions
(
{
ok
:
true
,
id
:
docId
,
rev
:
doc
.
_rev
},
command
,
doc
)
);
}
else
{
// we found a tree
/*
console.log( docTree );
console.log( prev_rev );
console.log( docId );
console.log( docPath );
console.log( docPathRev );
*/
doc
=
localstorage
.
getItem
(
docPathRev
);
console
.
log
(
doc
);
// check if rev_supplied is on the tree
// check if last node
// check if multiple leaves or one (do I need to???)
// if on tree and only leaf = expand
// if on tree and multiple leaves = ???
// if on tree, but not a leaf = error
// if not on tree, can be error or new version
// get revs_info from new document
// not available = error on PUT
// available = compare revs_info current and supplied
// start @root
// if nodes are the same and BRANCH, make sure they are branch and deleted if not the last nodes
// if nodes are not the same STOP
// add new kid to last branch
// continue with supplied revs_info to last version and add all the nodes on supplied revs_info
// this should "copy" the tree from supplied revs_info into the current document tree
// we have a tree, we know the last revision
//priv.getLastTreeRevision( docTree );
if
(
!
doc
)
{
}
if
(
doc
.
_rev
!==
prev_rev
)
{
that
.
error
(
priv
.
throwError
(
409
,
'
Revision supplied is not the latest revision
'
)
);
return
;
}
// update ...?
priv
.
documentObjectUpdate
(
doc
,
command
.
cloneDoc
());
// update document (and get it back)
doc
=
priv
.
updateDocument
(
doc
,
docPath
,
prev_rev
);
// update document tree
priv
.
updateDocumentTree
();
that
.
success
(
priv
.
manageOptions
(
{
ok
:
true
,
id
:
doci
d
,
rev
:
doc
.
_rev
},
{
ok
:
true
,
id
:
docI
d
,
rev
:
doc
.
_rev
},
command
,
doc
)
);
}
});
};
};
// end put
/**
* Saves
a document in the local storage
.
*
It will store the file in 'jio/local/USR/APP/FILE_NAME
'.
* @method put
* Saves
/updates an attachment of a specified document
.
*
attachment will be stored @ 'jio/local/USR/APP/FILE_NAME/ATTACHMENTID
'.
* @method put
Attachment
*/
that
.
put
=
function
(
command
)
{
that
.
put
Attachment
=
function
(
command
)
{
var
now
=
Date
.
now
();
// wait a little in order to simulate asynchronous saving
setTimeout
(
function
()
{
var
docid
,
doc
,
docpath
,
attmtid
,
attmt
,
attmtpath
,
prev_rev
,
rev
;
docid
=
command
.
getDocId
();
prev_rev
=
command
.
getDocInfo
(
'
_rev
'
);
docpath
=
'
jio/local/
'
+
priv
.
secured_username
+
'
/
'
+
priv
.
secured_applicationname
+
'
/
'
+
docid
;
// reading
// 404
doc
=
localstorage
.
getItem
(
docpath
);
if
(
!
doc
)
{
that
.
error
({
status
:
404
,
statusText
:
'
Not found
'
,
error
:
'
not_found
'
,
message
:
'
Document not found.
'
,
reason
:
'
document not found
'
reason
:
'
Document with specified id does not exist
'
});
return
;
}
// 409
if
(
doc
.
_rev
!==
prev_rev
)
{
// want to update an older document
that
.
error
({
status
:
409
,
statusText
:
'
Conflict
'
,
error
:
'
conflict
'
,
message
:
'
Document update conflict.
'
,
reason
:
'
document update conflict.
'
reason
:
'
Trying to update a previous document version
'
});
return
;
}
// it is the good document
// check attachment id
attmtid
=
command
.
getAttachmentId
();
if
(
attmtid
)
{
attmtpath
=
docpath
+
'
/
'
+
attmtid
;
// this is an attachment
attmt
=
localstorage
.
getItem
(
attmtpath
);
if
(
!
attmt
)
{
// there is no attachment to update
that
.
error
({
status
:
404
,
statusText
:
'
Not found
'
,
error
:
'
not_found
'
,
message
:
'
Document is missing attachment.
'
,
reason
:
'
document is missing attachment
'
});
return
;
// create _attachments
if
(
doc
.
_attachments
===
undefined
){
doc
.
_attachments
=
{};
}
// updating attachment
// create _attachments object for this attachment
if
(
doc
.
_attachments
[
attmtid
]
===
undefined
){
doc
.
_attachments
[
attmtid
]
=
{};
}
// set revpos
doc
.
_attachments
[
attmtid
].
revpos
=
parseInt
(
doc
.
_rev
.
split
(
'
-
'
)[
0
],
10
);
// store/update attachment
localstorage
.
setItem
(
attmtpath
,
command
.
getContent
());
}
else
{
// update document metadata
priv
.
documentObjectUpdate
(
doc
,
command
.
cloneDoc
());
// no attachment id specified
that
.
error
({
status
:
409
,
statusText
:
'
Conflict
'
,
error
:
'
conflict
'
,
message
:
'
Document update conflict.
'
,
reason
:
'
No attachment id specified
'
});
return
;
}
// rev = [number, hash]
rev
=
priv
.
generateNextRev
(
prev_rev
,
''
+
doc
+
'
'
+
now
+
''
);
doc
.
_rev
=
rev
.
join
(
'
-
'
);
...
...
@@ -379,7 +712,7 @@ var newLocalStorage = function ( spec, my ) {
)
);
});
};
// end put
};
// end put
Attachment
/**
* Loads a document from the local storage.
...
...
@@ -441,6 +774,7 @@ var newLocalStorage = function ( spec, my ) {
* the user.
* @method allDocs
*/
// ============== NOT MODIFIED YET ===============
that
.
allDocs
=
function
(
command
)
{
setTimeout
(
function
()
{
...
...
@@ -472,23 +806,77 @@ var newLocalStorage = function ( spec, my ) {
};
// end allDocs
/**
* Removes a document from the local storage.
* Removes a document
or attachment
from the local storage.
* It will also remove the path from the local file array.
* @method remove
*/
// ============== FILES WON'T BE DELETED YET ===============
that
.
remove
=
function
(
command
)
{
// wait a little in order to simulate asynchronous saving
setTimeout
(
function
()
{
var
secured_docid
=
priv
.
secureDocId
(
command
.
getDocId
()),
path
=
'
jio/local/
'
+
priv
.
secured_username
+
'
/
'
+
priv
.
secured_applicationname
+
'
/
'
+
secured_docid
;
if
(
!
priv
.
checkSecuredDocId
(
secured_docid
,
command
.
getDocId
(),
'
remove
'
))
{
return
;}
var
docid
,
doc
,
docpath
,
prev_rev
,
attmtid
,
attmt
,
attpath
;
docid
=
command
.
getDocId
();
docpath
=
'
jio/local/
'
+
priv
.
secured_username
+
'
/
'
+
priv
.
secured_applicationname
+
'
/
'
+
docid
;
prev_rev
=
command
.
getDocInfo
(
'
_rev
'
);
attmtid
=
command
.
getAttachmentId
();
// xxx remove attachment if exists
if
(
attmtid
){
attpath
=
docpath
+
'
/
'
+
attmtid
;
attmt
=
localstorage
.
getItem
(
attpath
);
if
(
attmt
){
// deleting
localstorage
.
deleteItem
(
path
);
priv
.
removeFileName
(
secured_docid
);
localstorage
.
deleteItem
(
attpath
);
priv
.
removeFileName
(
attpath
);
// xxx add new revision to tree here
that
.
success
({
ok
:
true
,
id
:
command
.
getDocId
()});
}
else
{
// the document does not exist
that
.
error
({
status
:
404
,
statusText
:
'
Not Found.
'
,
error
:
'
not_found
'
,
message
:
'
Document "
'
+
docid
+
'
" not found.
'
,
reason
:
'
missing
'
});
}
// xxx remove document if exists
}
else
{
doc
=
localstorage
.
getItem
(
docpath
);
// document exists
if
(
doc
){
// check for wrong revision
if
(
doc
.
_rev
===
prev_rev
){
localstorage
.
deleteItem
(
docpath
);
priv
.
removeFileName
(
docid
);
// xxx add new revision to tree here
that
.
success
({
ok
:
true
,
id
:
command
.
getDocId
()});
}
else
{
// the document does not exist
that
.
error
({
status
:
409
,
statusText
:
'
Conflict
'
,
error
:
'
conflict
'
,
message
:
'
Document update conflict.
'
,
reason
:
'
Trying to update an outdated revision
'
});
}
}
else
{
// the document does not exist
that
.
error
({
status
:
404
,
statusText
:
'
Not Found.
'
,
error
:
'
not_found
'
,
message
:
'
Document "
'
+
docid
+
'
" not found.
'
,
reason
:
'
missing
'
});
}
}
});
};
// end remove
...
...
src/jio/commands/command.js
View file @
31e65d17
...
...
@@ -23,8 +23,12 @@ var command = function(spec, my) {
priv
.
doc
=
spec
.
doc
||
{};
priv
.
doc
.
_id
=
priv
.
doc
.
_id
||
generateUuid
();
priv
.
docid
=
spec
.
docid
||
''
;
priv
.
content
=
typeof
spec
.
content
===
'
string
'
?
spec
.
content
:
// xxx fixed spec.content to spec.doc.content for PUTATTACHMENT
// xxx need extra check for GET, otherwise spec.doc is undefined
priv
.
content
=
spec
.
doc
===
undefined
?
undefined
:
typeof
spec
.
doc
.
content
===
'
string
'
?
spec
.
doc
.
content
:
undefined
;
priv
.
option
=
spec
.
options
||
{};
priv
.
callbacks
=
spec
.
callbacks
||
{};
...
...
src/jio/commands/putAttachmentCommand.js
View file @
31e65d17
src/jio/jio.outro.js
View file @
31e65d17
...
...
@@ -194,6 +194,7 @@
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
priv
.
addJob
(
postCommand
,{
doc
:
doc
,
options
:
param
.
options
,
...
...
@@ -223,6 +224,7 @@
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
priv
.
addJob
(
putCommand
,{
doc
:
doc
,
options
:
param
.
options
,
...
...
@@ -253,6 +255,7 @@
[
options
,
success
,
error
],
{
max_retry
:
3
}
);
priv
.
addJob
(
getCommand
,{
docid
:
id
,
options
:
param
.
options
,
...
...
@@ -282,6 +285,7 @@
[
options
,
success
,
callback
],
{
max_retry
:
0
}
);
priv
.
addJob
(
removeCommand
,{
doc
:
doc
,
options
:
param
.
options
,
...
...
@@ -311,6 +315,7 @@
[
options
,
success
.
error
],
{
max_retry
:
3
}
);
priv
.
addJob
(
allDocsCommand
,{
options
:
param
.
options
,
callbacks
:{
success
:
param
.
success
,
error
:
param
.
error
}
...
...
@@ -342,8 +347,9 @@
[
options
,
success
,
error
],
{
max_retry
:
0
}
);
priv
.
addJob
(
putAttachmentCommand
,{
doc
:{
_id
:
id
,
content
:
doc
},
doc
:{
_id
:
id
,
content
:
doc
,
_rev
:
rev
,
mimetype
:
mimetype
},
options
:
param
.
options
,
callbacks
:{
success
:
param
.
success
,
error
:
param
.
error
}
});
...
...
test/jiotests.js
View file @
31e65d17
...
...
@@ -5,21 +5,6 @@
Base64
=
loader
.
Base64
,
$
=
loader
.
jQuery
;
//// clear jio localstorage
(
function
()
{
var
k
,
storageObject
=
LocalOrCookieStorage
.
getAll
();
for
(
k
in
storageObject
)
{
var
splitk
=
k
.
split
(
'
/
'
);
if
(
splitk
[
0
]
===
'
jio
'
)
{
LocalOrCookieStorage
.
deleteItem
(
k
);
}
}
var
d
=
document
.
createElement
(
'
div
'
);
d
.
setAttribute
(
'
id
'
,
'
log
'
);
document
.
querySelector
(
'
body
'
).
appendChild
(
d
);
}());
//// end clear jio localstorage
//// Tools
var
empty_fun
=
function
(){},
contains
=
function
(
array
,
content
)
{
...
...
@@ -34,10 +19,27 @@ contains = function (array,content) {
}
return
false
;
},
clean_up_local_storage_function
=
function
(){
var
k
,
storageObject
=
LocalOrCookieStorage
.
getAll
();
for
(
k
in
storageObject
)
{
var
splitk
=
k
.
split
(
'
/
'
);
if
(
splitk
[
0
]
===
'
jio
'
)
{
LocalOrCookieStorage
.
deleteItem
(
k
);
}
}
var
d
=
document
.
createElement
(
'
div
'
);
d
.
setAttribute
(
'
id
'
,
'
log
'
);
document
.
querySelector
(
'
body
'
).
appendChild
(
d
);
// remove everything
localStorage
.
clear
();
},
base_tick
=
30000
,
basic_test_function_generator
=
function
(
o
,
res
,
value
,
message
)
{
return
function
(
err
,
val
)
{
var
jobstatus
=
(
err
?
'
fail
'
:
'
done
'
);
var
jobstatus
=
(
err
?
'
fail
'
:
'
done
'
),
val
=
(
isEmptyObject
(
value
)
&&
isUUID
(
val
.
_id
)
)
?
{}
:
val
;
switch
(
res
)
{
case
'
status
'
:
err
=
err
||
{};
val
=
err
.
status
;
...
...
@@ -187,6 +189,31 @@ revs_infoContains = function (revs_info, rev) {
}
}
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
;
}
}
return
true
;
};
//// end tools
...
...
@@ -256,12 +283,36 @@ test ('All tests', function () {
o
.
clock
.
tick
(
base_tick
);
o
.
spy
=
basic_spy_function
;
o
.
tick
=
basic_tick_function
;
// All Ok Dummy Storage
o
.
jio
=
JIO
.
newJio
({
'
type
'
:
'
dummyallok
'
});
// save
o
.
spy
(
o
,
'
value
'
,{
ok
:
true
,
id
:
'
file
'
},
'
dummyallok saving
'
);
o
.
jio
.
put
({
_id
:
'
file
'
,
content
:
'
content
'
},
o
.
f
);
// 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
.
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
);
});
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
);
});
o
.
tick
(
o
);
/*
// load
o.spy(o,'value',{_id:'file',content:'content',_last_modified:15000,
_creation_date:10000},'dummyallok loading');
...
...
@@ -348,8 +399,10 @@ test ('All tests', function () {
o.jio.allDocs (o.f);
o.tick(o);
o.jio.stop();
});
*/
});
/*
module ( 'Jio Job Managing' );
test ('Simple Job Elimination', function () {
...
...
@@ -533,45 +586,221 @@ test ('Restore old Jio', function() {
o.jio.stop();
});
*/
module
(
'
Jio LocalStorage
'
);
test
(
'
Document save
'
,
function
()
{
// Test if LocalStorage can save documents.
// We launch a saving to localstorage and we check if the file is
// realy saved. Then save again and check if
// ============================== POST ==========================
test
(
'
Post
'
,
function
(){
// runs following assertions
// a) POST with id - should be an error
// b) POST with attachment - should be an error
// c) POST with content
// d) check that document is created with UUID.revision
// e) check that document revision tree is created
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
];
}
};
var
o
=
{};
o
.
t
=
this
;
o
.
clock
=
o
.
t
.
sandbox
.
useFakeTimers
();
o
.
clock
.
tick
(
base_tick
);
o
.
spy
=
basic_spy_function
;
o
.
tick
=
function
(
o
,
tick
,
value
,
fun
)
{
o
.
clean
=
clean_up_local_storage_function
();
// test functions
o
.
checkReply
=
function
(
o
,
tick
,
fun
){
basic_tick_function
(
o
,
tick
,
fun
);
};
o
.
checkFile
=
function
(
response
,
o
,
tick
,
value
,
fun
)
{
o
.
tmp
=
localstorage
.
getItem
(
'
jio/local/MrPost/jiotests/
'
+
response
.
id
+
'
/
'
+
response
.
rev
);
// fake it
o
.
tmp
.
ok
=
true
;
delete
o
.
tmp
.
_revisions
;
delete
o
.
tmp
.
_revs_info
;
if
(
o
.
tmp
)
{
deepEqual
(
o
.
tmp
,{
"
ok
"
:
response
.
ok
,
"
_id
"
:
response
.
id
,
"
_rev
"
:
response
.
rev
,
},
'
document was created
'
);
}
else
{
ok
(
false
,
'
document was not created
'
);
}
};
o
.
checkTree
=
function
(
response
,
o
,
tick
,
value
,
fun
)
{
o
.
tmp
=
localstorage
.
getItem
(
'
jio/local/MrPost/jiotests/
'
+
response
.
id
+
'
/revision_tree
'
);
if
(
o
.
tmp
)
{
deepEqual
(
o
.
tmp
,{
"
type
"
:
'
leaf
'
,
"
status
"
:
'
available
'
,
"
rev
"
:
response
.
rev
,
"
kids
"
:{}
},
'
document tree was created
'
);
}
else
{
ok
(
false
,
'
document tree was not created
'
);
}
};
// let's go
o
.
jio
=
JIO
.
newJio
({
type
:
'
local
'
,
username
:
'
MrPost
'
,
applicationname
:
'
jiotests
'
});
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
.
jio
.
post
({
"
_id
"
:
'
file
'
,
"
content
"
:
'
content
'
},
o
.
f
);
// TEST a) POST with id
o
.
checkReply
(
o
,
null
,
true
);
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
.
jio
.
post
({
"
_id
"
:
'
file/ABC
'
,
"
mimetype
"
:
'
text/html
'
,
"
content
"
:
'
<b>hello</b>
'
},
o
.
f
);
// TEST b) POST attachment
o
.
checkReply
(
o
,
null
,
true
);
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
);
// TEST d) check if document is created and correct
o
.
checkFile
(
response
,
o
,
null
,
true
);
// TEST e) check if document tree is created and correct
o
.
checkTree
(
response
,
o
,
null
,
true
);
});
// c) TEST POST content
o
.
checkReply
(
o
,
null
,
true
);
o
.
jio
.
stop
();
o
.
clean
;
});
// ============================== PUT ==========================
/*
test ('Put', function(){
// runs following assertions
// a)
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.clock.tick(base_tick);
o.spy = basic_spy_function;
o.clean = clean_up_local_storage_function();
// test functions
o.checkReply = function(o,tick,fun){
basic_tick_function(o,tick,fun);
};
o.checkFile = function (response, o, tick, value, fun) {
o.tmp =
LocalOrCookieStorage
.
getItem
(
'
jio/local/MrSaveName/jiotests/file
'
);
localstorage.getItem('jio/local/MrSaveName/jiotests/'+ response.id+'/'+response.rev );
// fake it
o.tmp.ok = true;
delete o.tmp._revisions;
delete o.tmp._revs_info;
if (o.tmp) {
o
.
tmp
.
lmcd
=
(
o
.
tmp
.
_last_modified
===
o
.
tmp
.
_creation_date
);
delete
o
.
tmp
.
_last_modified
;
delete
o
.
tmp
.
_creation_date
;
deepEqual
(
o
.
tmp
,{
_id
:
'
file
'
,
content
:
'
content
'
,
lmcd
:
value
}
,
'
check saved document
'
);
deepEqual (o.tmp,{
"ok":response.ok,
"_id":response.id,
"_rev":response.rev
,
},'document was created
');
} else {
ok
(
false
,
'
document
is not saved!
'
);
ok (false, 'document
was not created
');
}
};
o.checkTree = function ( response, o, tick, value, fun) {
o
.
jio
=
JIO
.
newJio
({
type
:
'
local
'
,
username
:
'
MrSaveName
'
,
applicationname
:
'
jiotests
'
});
// save and check document existence
o
.
spy
(
o
,
'
value
'
,{
ok
:
true
,
id
:
'
file
'
},
'
saving document
'
);
o
.
jio
.
put
({
_id
:
'
file
'
,
content
:
'
content
'
},
o
.
f
);
o
.
tick
(
o
,
null
,
true
);
o.tmp =
localstorage.getItem('jio/local/MrPut/jiotests/'+ response.id+'/revision_tree' );
if (o.tmp) {
deepEqual (o.tmp,{
"type":'leaf',
"status":'available',
"rev":response.rev,
"kids":{}
},'document tree was created');
} else {
ok (false, 'document tree was not created');
}
o
.
spy
(
o
,
'
value
'
,{
ok
:
true
,
id
:
'
file
'
},
'
saving document
'
);
o
.
jio
.
put
({
_id
:
'
file
'
,
content
:
'
content
'
},
o
.
f
);
o
.
tick
(
o
,
null
,
false
);
};
// let's go
o.jio = JIO.newJio({ type:'local', username:'MrPut',
applicationname:'jiotests' });
o.spy (o,'value',{ },'');
o.jio.post({"_id":'file',"content":'content'},o.f);
// a) TEST
o.checkReply(o,null,true);
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);
// d) check document is created and correct
o.checkFile(response, o, null, true);
// e) check document tree is created and correct
o.checkTree(response, o, null, true);
});
// c) POST content - o.spy must be in callback to access response
o.checkReply(o,null,true);
o.jio.stop();
o.clean;
});
*/
/*
test ('Document load', function () {
// Test if LocalStorage can load documents.
// We launch a loading from localstorage and we check if the file is
...
...
@@ -599,7 +828,7 @@ test ('Document load', function () {
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.
...
...
@@ -650,7 +879,7 @@ test ('Get document list', function () {
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
...
...
@@ -677,7 +906,8 @@ test ('Document remove', function () {
o.jio.stop();
});
*/
/*
module ('Jio DAVStorage');
test ('Document load', function () {
...
...
@@ -2264,7 +2494,7 @@ test ('Get revision List', function () {
o.jio.stop();
});
*/
};
// end thisfun
if
(
window
.
requirejs
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment