summaryrefslogtreecommitdiff
path: root/rel
diff options
context:
space:
mode:
authorAdam Kocoloski <adam.kocoloski@gmail.com>2011-01-20 12:43:37 -0500
committerAdam Kocoloski <adam.kocoloski@gmail.com>2011-01-20 13:05:41 -0500
commitf79d0a666a5fb9541a0925db5111208a94631065 (patch)
tree392d85a8a9887ddc8f6268a48a65537b21734a7d /rel
parent2ea18bdaa19ea7f2da1a5dccce65d50cf0efc64d (diff)
parent94286611038e661487382ed834103853e88fdf69 (diff)
Merge CouchDB 1.0.2 release candidate
Conflicts: Makefile.am acinclude.m4.in apps/couch/src/couch_db.erl apps/couch/src/couch_db_updater.erl apps/couch/src/couch_rep.erl apps/couch/src/couch_rep_reader.erl apps/couch/src/couch_view.erl apps/couch/src/couch_view_group.erl rel/overlay/etc/default.ini share/Makefile.am src/couchdb/couch_query_servers.erl src/ibrowse/Makefile.am src/ibrowse/ibrowse.app.in src/ibrowse/ibrowse.erl src/ibrowse/ibrowse_app.erl src/ibrowse/ibrowse_http_client.erl src/ibrowse/ibrowse_lb.erl src/ibrowse/ibrowse_lib.erl src/ibrowse/ibrowse_sup.erl src/ibrowse/ibrowse_test.erl src/mochiweb/mochijson2.erl test/etap/112-replication-missing-revs.t test/etap/113-replication-attachment-comp.t test/etap/140-attachment-comp.t
Diffstat (limited to 'rel')
-rw-r--r--rel/overlay/etc/default.ini24
-rw-r--r--rel/overlay/share/www/database.html16
-rw-r--r--rel/overlay/share/www/image/spinner.gifbin1849 -> 3008 bytes
-rw-r--r--rel/overlay/share/www/index.html2
-rw-r--r--rel/overlay/share/www/script/couch.js80
-rw-r--r--rel/overlay/share/www/script/couch_test_runner.js26
-rw-r--r--rel/overlay/share/www/script/couch_tests.js1
-rw-r--r--rel/overlay/share/www/script/futon.browse.js35
-rw-r--r--rel/overlay/share/www/script/futon.format.js5
-rw-r--r--rel/overlay/share/www/script/futon.js17
-rw-r--r--rel/overlay/share/www/script/jquery.couch.js10
-rw-r--r--rel/overlay/share/www/script/test/attachment_names.js4
-rw-r--r--rel/overlay/share/www/script/test/attachment_paths.js14
-rw-r--r--rel/overlay/share/www/script/test/attachment_views.js4
-rw-r--r--rel/overlay/share/www/script/test/attachments.js28
-rw-r--r--rel/overlay/share/www/script/test/attachments_multipart.js10
-rw-r--r--rel/overlay/share/www/script/test/auth_cache.js31
-rw-r--r--rel/overlay/share/www/script/test/basics.js10
-rw-r--r--rel/overlay/share/www/script/test/bulk_docs.js10
-rw-r--r--rel/overlay/share/www/script/test/compact.js6
-rw-r--r--rel/overlay/share/www/script/test/conflicts.js2
-rw-r--r--rel/overlay/share/www/script/test/cookie_auth.js20
-rw-r--r--rel/overlay/share/www/script/test/design_docs.js45
-rw-r--r--rel/overlay/share/www/script/test/erlang_views.js2
-rw-r--r--rel/overlay/share/www/script/test/etags_views.js2
-rw-r--r--rel/overlay/share/www/script/test/list_views.js2
-rw-r--r--rel/overlay/share/www/script/test/method_override.js2
-rw-r--r--rel/overlay/share/www/script/test/proxyauth.js13
-rw-r--r--rel/overlay/share/www/script/test/purge.js16
-rw-r--r--rel/overlay/share/www/script/test/recreate_doc.js2
-rw-r--r--rel/overlay/share/www/script/test/reduce.js9
-rw-r--r--rel/overlay/share/www/script/test/reduce_builtin.js9
-rw-r--r--rel/overlay/share/www/script/test/replication.js196
-rw-r--r--rel/overlay/share/www/script/test/rewrite.js15
-rw-r--r--rel/overlay/share/www/script/test/security_validation.js21
-rw-r--r--rel/overlay/share/www/script/test/stats.js10
-rw-r--r--rel/overlay/share/www/script/test/users_db.js23
-rw-r--r--rel/overlay/share/www/script/test/view_errors.js25
-rw-r--r--rel/overlay/share/www/script/test/view_multi_key_design.js6
-rw-r--r--rel/overlay/share/www/script/test/view_sandboxing.js92
-rw-r--r--rel/overlay/share/www/script/test/view_update_seq.js4
-rw-r--r--rel/overlay/share/www/session.html2
42 files changed, 634 insertions, 217 deletions
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index ecf340d3..cf06a1ec 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -19,21 +19,22 @@ docroot = {{prefix}}/share/www
[httpd]
port = {{backend_port}}
-bind_address = 0.0.0.0
-authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
+bind_address = 127.0.0.1
+max_connections = 2048
+authentication_handlers = {couch_httpd_oauth, oauth_authentication_handler}, {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}
default_handler = {couch_httpd_db, handle_request}
-WWW-Authenticate = Basic realm="Cloudant Private Database"
-backlog = 512
secure_rewrites = true
+vhost_global_handlers = _utils, _uuids, _session, _oauth, _users
+allow_jsonp = false
[log]
file = {{prefix}}/var/log/bigcouch.log
level = info
+include_sasl = true
[couch_httpd_auth]
+authentication_db = _users
authentication_redirect = /_utils/session.html
-authentication_db = users
-secret = replace this with a real secret in your local.ini file
require_valid_user = false
timeout = 600 ; number of seconds before automatic logout
auth_cache_size = 50 ; size is number of cache entries
@@ -69,7 +70,6 @@ _stats = {couch_httpd_stats_handlers, handle_stats_req}
_log = {couch_httpd_misc_handlers, handle_log_req}
_session = {couch_httpd_auth, handle_session_req}
_oauth = {couch_httpd_oauth, handle_oauth_req}
-_user = {couch_httpd_auth, handle_user_req}
_system = {chttpd_misc, handle_system_req}
[httpd_db_handlers]
@@ -110,5 +110,11 @@ compression_level = 8 ; from 1 (lowest, fastest) to 9 (highest, slowest), 0 to d
compressible_types = text/*, application/javascript, application/json, application/xml
[replicator]
-max_http_sessions = 10
-max_http_pipeline_size = 10
+max_http_sessions = 20
+max_http_pipeline_size = 50
+; set to true to validate peer certificates
+verify_ssl_certificates = false
+; file containing a list of peer trusted certificates (PEM format)
+; ssl_trusted_certificates_file = /etc/ssl/certs/ca-certificates.crt
+; maximum peer certificate depth (must be set even if certificate validation is off)
+ssl_certificate_max_depth = 3
diff --git a/rel/overlay/share/www/database.html b/rel/overlay/share/www/database.html
index 39507398..9a9f121e 100644
--- a/rel/overlay/share/www/database.html
+++ b/rel/overlay/share/www/database.html
@@ -37,9 +37,13 @@ specific language governing permissions and limitations under the License.
$(function() {
if (page.redirecting) return;
- $("h1 strong").html('<a href="?' + page.db.name + '">' + page.db.name + '</a>');
+ $("h1 strong").text(page.db.name);
var viewPath = page.viewName || "_all_docs";
if (viewPath != "_temp_view" && viewPath != "_design_docs") {
+ viewPath = $.map(viewPath.split("/"), function (part) {
+ return encodeURIComponent(part);
+ }).join("/");
+
$("h1 a.raw").attr("href", "/" + encodeURIComponent(page.db.name) +
"/" + viewPath);
}
@@ -71,17 +75,17 @@ specific language governing permissions and limitations under the License.
});
// Restore preferences/state
- $("#documents thead th.key").toggleClass("desc", $.futon.storage.get("desc"));
- var reduce = $.futon.storage.get("reduce");
+ $("#documents thead th.key").toggleClass("desc", !!$.futon.storage.get("desc"));
+ var reduce = !!$.futon.storage.get("reduce");
$("#reduce :checkbox")[0].checked = reduce;
- $("#grouplevel select").val($.futon.storage.get("group_level"));
+ $("#grouplevel select").val(parseInt($.futon.storage.get("group_level")));
$("#grouplevel").toggleClass("disabled", !reduce).find("select").each(function() {
this.disabled = !reduce;
});
- $("#perpage").val($.futon.storage.get("per_page"));
+ $("#perpage").val(parseInt($.futon.storage.get("per_page")));
- var staleViews = $.futon.storage.get("stale");
+ var staleViews = !!$.futon.storage.get("stale");
$("#staleviews :checkbox")[0].checked = staleViews;
page.populateViewsMenu();
diff --git a/rel/overlay/share/www/image/spinner.gif b/rel/overlay/share/www/image/spinner.gif
index f27d7cd4..6239655e 100644
--- a/rel/overlay/share/www/image/spinner.gif
+++ b/rel/overlay/share/www/image/spinner.gif
Binary files differ
diff --git a/rel/overlay/share/www/index.html b/rel/overlay/share/www/index.html
index e34dbde1..975f5986 100644
--- a/rel/overlay/share/www/index.html
+++ b/rel/overlay/share/www/index.html
@@ -34,7 +34,7 @@ specific language governing permissions and limitations under the License.
this.updateSelection(location.pathname + "index.html");
});
}
- var dbsPerPage = $.futon.storage.get("per_page");
+ var dbsPerPage = parseInt($.futon.storage.get("per_page"));
if (dbsPerPage) $("#perpage").val(dbsPerPage);
$("#perpage").change(function() {
page.updateDatabaseListing();
diff --git a/rel/overlay/share/www/script/couch.js b/rel/overlay/share/www/script/couch.js
index 33fd82ba..ca860bd5 100644
--- a/rel/overlay/share/www/script/couch.js
+++ b/rel/overlay/share/www/script/couch.js
@@ -22,17 +22,17 @@ function CouchDB(name, httpHeaders) {
this.last_req = null;
this.request = function(method, uri, requestOptions) {
- requestOptions = requestOptions || {}
- requestOptions.headers = combine(requestOptions.headers, httpHeaders)
+ requestOptions = requestOptions || {};
+ requestOptions.headers = combine(requestOptions.headers, httpHeaders);
return CouchDB.request(method, uri, requestOptions);
- }
+ };
// Creates the database on the server
this.createDb = function() {
this.last_req = this.request("PUT", this.uri);
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
// Deletes the database on the server
this.deleteDb = function() {
@@ -42,7 +42,7 @@ function CouchDB(name, httpHeaders) {
}
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
// Save a document to the database
this.save = function(doc, options) {
@@ -57,7 +57,7 @@ function CouchDB(name, httpHeaders) {
var result = JSON.parse(this.last_req.responseText);
doc._rev = result.rev;
return result;
- }
+ };
// Open a document from the database
this.open = function(docId, options) {
@@ -68,7 +68,7 @@ function CouchDB(name, httpHeaders) {
}
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
// Deletes a document from the database
this.deleteDoc = function(doc) {
@@ -79,7 +79,7 @@ function CouchDB(name, httpHeaders) {
doc._rev = result.rev; //record rev in input document
doc._deleted = true;
return result;
- }
+ };
// Deletes an attachment from a document
this.deleteDocAttachment = function(doc, attachment_name) {
@@ -89,18 +89,18 @@ function CouchDB(name, httpHeaders) {
var result = JSON.parse(this.last_req.responseText);
doc._rev = result.rev; //record rev in input document
return result;
- }
+ };
this.bulkSave = function(docs, options) {
// first prepoulate the UUIDs for new documents
- var newCount = 0
+ var newCount = 0;
for (var i=0; i<docs.length; i++) {
if (docs[i]._id == undefined) {
newCount++;
}
}
var newUuids = CouchDB.newUuids(docs.length);
- var newCount = 0
+ var newCount = 0;
for (var i=0; i<docs.length; i++) {
if (docs[i]._id == undefined) {
docs[i]._id = newUuids.pop();
@@ -127,13 +127,13 @@ function CouchDB(name, httpHeaders) {
}
return results;
}
- }
+ };
this.ensureFullCommit = function() {
this.last_req = this.request("POST", this.uri + "_ensure_full_commit");
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
// Applies the map function to the contents of database and returns the results.
this.query = function(mapFun, reduceFun, options, keys, language) {
@@ -163,7 +163,7 @@ function CouchDB(name, httpHeaders) {
});
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.view = function(viewname, options, keys) {
var viewParts = viewname.split('/');
@@ -182,21 +182,21 @@ function CouchDB(name, httpHeaders) {
}
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
// gets information about the database
this.info = function() {
this.last_req = this.request("GET", this.uri);
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
// gets information about a design doc
this.designInfo = function(docid) {
this.last_req = this.request("GET", this.uri + docid + "/_info");
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.allDocs = function(options,keys) {
if(!keys) {
@@ -211,7 +211,7 @@ function CouchDB(name, httpHeaders) {
}
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.designDocs = function() {
return this.allDocs({startkey:"_design", endkey:"_design0"});
@@ -222,19 +222,19 @@ function CouchDB(name, httpHeaders) {
+ encodeOptions(options));
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.compact = function() {
this.last_req = this.request("POST", this.uri + "_compact");
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.viewCleanup = function() {
this.last_req = this.request("POST", this.uri + "_view_cleanup");
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.setDbProperty = function(propId, propValue) {
this.last_req = this.request("PUT", this.uri + propId,{
@@ -242,13 +242,13 @@ function CouchDB(name, httpHeaders) {
});
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.getDbProperty = function(propId) {
this.last_req = this.request("GET", this.uri + propId);
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.setSecObj = function(secObj) {
this.last_req = this.request("PUT", this.uri + "_security",{
@@ -256,21 +256,21 @@ function CouchDB(name, httpHeaders) {
});
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
this.getSecObj = function() {
this.last_req = this.request("GET", this.uri + "_security");
CouchDB.maybeThrowError(this.last_req);
return JSON.parse(this.last_req.responseText);
- }
+ };
// Convert a options object to an url query string.
// ex: {key:'value',key2:'value2'} becomes '?key="value"&key2="value2"'
function encodeOptions(options) {
- var buf = []
+ var buf = [];
if (typeof(options) == "object" && options !== null) {
for (var name in options) {
- if (!options.hasOwnProperty(name)) { continue };
+ if (!options.hasOwnProperty(name)) { continue; };
var value = options[name];
if (name == "key" || name == "startkey" || name == "endkey") {
value = toJSON(value);
@@ -318,7 +318,7 @@ CouchDB.login = function(name, password) {
+ encodeURIComponent(password)
});
return JSON.parse(CouchDB.last_req.responseText);
-}
+};
CouchDB.logout = function() {
CouchDB.last_req = CouchDB.request("DELETE", "/_session", {
@@ -326,7 +326,7 @@ CouchDB.logout = function() {
"X-CouchDB-WWW-Authenticate": "Cookie"}
});
return JSON.parse(CouchDB.last_req.responseText);
-}
+};
CouchDB.session = function(options) {
options = options || {};
@@ -346,7 +346,7 @@ CouchDB.prepareUserDoc = function(user_doc, new_password) {
}
user_doc.type = "user";
if (!user_doc.roles) {
- user_doc.roles = []
+ user_doc.roles = [];
}
return user_doc;
};
@@ -370,7 +370,7 @@ CouchDB.getVersion = function() {
CouchDB.last_req = CouchDB.request("GET", "/");
CouchDB.maybeThrowError(CouchDB.last_req);
return JSON.parse(CouchDB.last_req.responseText).version;
-}
+};
CouchDB.replicate = function(source, target, rep_options) {
rep_options = rep_options || {};
@@ -384,7 +384,7 @@ CouchDB.replicate = function(source, target, rep_options) {
});
CouchDB.maybeThrowError(CouchDB.last_req);
return JSON.parse(CouchDB.last_req.responseText);
-}
+};
CouchDB.newXhr = function() {
if (typeof(XMLHttpRequest) != "undefined") {
@@ -394,16 +394,16 @@ CouchDB.newXhr = function() {
} else {
throw new Error("No XMLHTTPRequest support detected");
}
-}
+};
CouchDB.request = function(method, uri, options) {
- options = options || {};
- options.headers = options.headers || {};
+ options = typeof(options) == 'object' ? options : {};
+ options.headers = typeof(options.headers) == 'object' ? options.headers : {};
options.headers["Content-Type"] = options.headers["Content-Type"] || options.headers["content-type"] || "application/json";
options.headers["Accept"] = options.headers["Accept"] || options.headers["accept"] || "application/json";
var req = CouchDB.newXhr();
if(uri.substr(0, "http://".length) != "http://") {
- uri = CouchDB.urlPrefix + uri
+ uri = CouchDB.urlPrefix + uri;
}
req.open(method, uri, false);
if (options.headers) {
@@ -415,7 +415,7 @@ CouchDB.request = function(method, uri, options) {
}
req.send(options.body || "");
return req;
-}
+};
CouchDB.requestStats = function(module, key, test) {
var query_arg = "";
@@ -426,7 +426,7 @@ CouchDB.requestStats = function(module, key, test) {
var url = "/_stats/" + module + "/" + key + query_arg;
var stat = CouchDB.request("GET", url).responseText;
return JSON.parse(stat)[module][key];
-}
+};
CouchDB.uuids_cache = [];
@@ -449,7 +449,7 @@ CouchDB.newUuids = function(n, buf) {
CouchDB.uuids_cache.concat(result.uuids.slice(0, buf));
return result.uuids.slice(buf);
}
-}
+};
CouchDB.maybeThrowError = function(req) {
if (req.status >= 400) {
@@ -460,7 +460,7 @@ CouchDB.maybeThrowError = function(req) {
}
throw result;
}
-}
+};
CouchDB.params = function(options) {
options = options || {};
diff --git a/rel/overlay/share/www/script/couch_test_runner.js b/rel/overlay/share/www/script/couch_test_runner.js
index 451a454a..55a6533f 100644
--- a/rel/overlay/share/www/script/couch_test_runner.js
+++ b/rel/overlay/share/www/script/couch_test_runner.js
@@ -14,6 +14,13 @@
function loadScript(url) {
+ // disallow loading remote URLs
+ if((url.substr(0, 7) == "http://")
+ || (url.substr(0, 2) == "//")
+ || (url.substr(0, 5) == "data:")
+ || (url.substr(0, 11) == "javascript:")) {
+ throw "Not loading remote test scripts";
+ }
if (typeof document != "undefined") document.write('<script src="'+url+'"></script>');
};
@@ -21,7 +28,7 @@ function patchTest(fun) {
var source = fun.toString();
var output = "";
var i = 0;
- var testMarker = "T("
+ var testMarker = "T(";
while (i < source.length) {
var testStart = source.indexOf(testMarker, i);
if (testStart == -1) {
@@ -232,13 +239,13 @@ function saveTestReport(report) {
$.couch.info({success : function(node_info) {
report.node = node_info;
db.saveDoc(report);
- }})
+ }});
};
var createDb = function() {
db.create({success: function() {
db.info({success:saveReport});
}});
- }
+ };
db.info({error: createDb, success:saveReport});
}
};
@@ -302,7 +309,7 @@ function T(arg1, arg2, testName) {
.find("code").text(message).end()
.appendTo($("td.details ol", currentRow));
}
- numFailures += 1
+ numFailures += 1;
}
}
@@ -311,6 +318,11 @@ function TEquals(expected, actual, testName) {
"', got '" + repr(actual) + "'", testName);
}
+function TEqualsIgnoreCase(expected, actual, testName) {
+ T(equals(expected.toUpperCase(), actual.toUpperCase()), "expected '" + repr(expected) +
+ "', got '" + repr(actual) + "'", testName);
+}
+
function equals(a,b) {
if (a === b) return true;
try {
@@ -331,18 +343,18 @@ function repr(val) {
}
function makeDocs(start, end, templateDoc) {
- var templateDocSrc = templateDoc ? JSON.stringify(templateDoc) : "{}"
+ var templateDocSrc = templateDoc ? JSON.stringify(templateDoc) : "{}";
if (end === undefined) {
end = start;
start = 0;
}
- var docs = []
+ var docs = [];
for (var i = start; i < end; i++) {
var newDoc = eval("(" + templateDocSrc + ")");
newDoc._id = (i).toString();
newDoc.integer = i;
newDoc.string = (i).toString();
- docs.push(newDoc)
+ docs.push(newDoc);
}
return docs;
}
diff --git a/rel/overlay/share/www/script/couch_tests.js b/rel/overlay/share/www/script/couch_tests.js
index c5257ea6..896b3538 100644
--- a/rel/overlay/share/www/script/couch_tests.js
+++ b/rel/overlay/share/www/script/couch_tests.js
@@ -32,6 +32,7 @@ loadTest("basics.js");
loadTest("all_docs.js");
loadTest("attachments.js");
loadTest("attachments_multipart.js");
+loadTest("attachment_conflicts.js");
loadTest("attachment_names.js");
loadTest("attachment_paths.js");
loadTest("attachment_views.js");
diff --git a/rel/overlay/share/www/script/futon.browse.js b/rel/overlay/share/www/script/futon.browse.js
index c8c1c420..a3f6e8cb 100644
--- a/rel/overlay/share/www/script/futon.browse.js
+++ b/rel/overlay/share/www/script/futon.browse.js
@@ -97,7 +97,10 @@
// Page class for browse/database.html
CouchDatabasePage: function() {
var urlParts = location.search.substr(1).split("/");
- var dbName = decodeURIComponent(urlParts.shift());
+ var dbName = decodeURIComponent(urlParts.shift())
+
+ var dbNameRegExp = new RegExp("[^a-z0-9\_\$\(\)\+\/\-]", "g");
+ dbName = dbName.replace(dbNameRegExp, "");
$.futon.storage.declareWithPrefix(dbName + ".", {
desc: {},
@@ -113,18 +116,19 @@
var viewName = (urlParts.length > 0) ? urlParts.join("/") : null;
if (viewName) {
- $.futon.storage.set("view", viewName);
+ $.futon.storage.set("view", decodeURIComponent(viewName));
} else {
viewName = $.futon.storage.get("view");
if (viewName) {
this.redirecting = true;
location.href = "database.html?" + encodeURIComponent(dbName) +
- "/" + viewName;
+ "/" + encodeURIComponent(viewName);
}
}
var db = $.couch.db(dbName);
this.dbName = dbName;
+ viewName = decodeURIComponent(viewName);
this.viewName = viewName;
this.viewLanguage = "javascript";
this.db = db;
@@ -150,9 +154,13 @@
db.compact({success: function(resp) { callback() }});
break;
case "compact_views":
- var groupname = page.viewName.substring(8,
- page.viewName.indexOf("/_view"));
- db.compactView(groupname, {success: function(resp) { callback() }});
+ var idx = page.viewName.indexOf("/_view");
+ if (idx == -1) {
+ alert("Compact Views requires focus on a view!");
+ } else {
+ var groupname = page.viewName.substring(8, idx);
+ db.compactView(groupname, {success: function(resp) { callback() }});
+ }
break;
case "view_cleanup":
db.viewCleanup({success: function(resp) { callback() }});
@@ -372,7 +380,8 @@
var path = $.couch.encodeDocId(doc._id) + "/_view/" +
encodeURIComponent(viewNames[j]);
var option = $(document.createElement("option"))
- .attr("value", path).text(viewNames[j]).appendTo(optGroup);
+ .attr("value", path).text(encodeURIComponent(viewNames[j]))
+ .appendTo(optGroup);
if (path == viewName) {
option[0].selected = true;
}
@@ -408,7 +417,7 @@
}
var viewCode = resp.views[localViewName];
page.viewLanguage = resp.language || "javascript";
- $("#language").val(page.viewLanguage);
+ $("#language").val(encodeURIComponent(page.viewLanguage));
page.updateViewEditor(viewCode.map, viewCode.reduce || "");
$("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled");
page.storedViewCode = viewCode;
@@ -420,7 +429,7 @@
page.updateViewEditor(page.storedViewCode.map,
page.storedViewCode.reduce || "");
page.viewLanguage = page.storedViewLanguage;
- $("#language").val(page.viewLanguage);
+ $("#language").val(encodeURIComponent(page.viewLanguage));
$("#viewcode button.revert, #viewcode button.save").attr("disabled", "disabled");
page.isDirty = false;
if (callback) callback();
@@ -504,7 +513,8 @@
callback({
docid: "Cannot save to " + data.docid +
" because its language is \"" + doc.language +
- "\", not \"" + page.viewLanguage + "\"."
+ "\", not \"" +
+ encodeURIComponent(page.viewLanguage) + "\"."
});
return;
}
@@ -569,7 +579,7 @@
this.updateDesignDocLink = function() {
if (viewName && /^_design/.test(viewName)) {
- var docId = "_design/" + decodeURIComponent(viewName.split("/")[1]);
+ var docId = "_design/" + encodeURIComponent(decodeURIComponent(viewName).split("/")[1]);
$("#designdoc-link").attr("href", "document.html?" +
encodeURIComponent(dbName) + "/" + $.couch.encodeDocId(docId)).text(docId);
} else {
@@ -765,8 +775,7 @@
if (page.isDirty) {
db.query(currentMapCode, currentReduceCode, page.viewLanguage, options);
} else {
- var viewParts = viewName.split('/');
-
+ var viewParts = decodeURIComponent(viewName).split('/');
if ($.futon.storage.get("stale")) {
options.stale = "ok";
}
diff --git a/rel/overlay/share/www/script/futon.format.js b/rel/overlay/share/www/script/futon.format.js
index 0d536e36..8d9b7f5c 100644
--- a/rel/overlay/share/www/script/futon.format.js
+++ b/rel/overlay/share/www/script/futon.format.js
@@ -16,7 +16,10 @@
escape: function(string) {
return string.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
- .replace(/>/g, "&gt;");
+ .replace(/>/g, "&gt;")
+ .replace(/"/, "&quot;")
+ .replace(/'/, "&#39;")
+ ;
},
// JSON pretty printing
diff --git a/rel/overlay/share/www/script/futon.js b/rel/overlay/share/www/script/futon.js
index b15a5eec..c4647ed1 100644
--- a/rel/overlay/share/www/script/futon.js
+++ b/rel/overlay/share/www/script/futon.js
@@ -215,9 +215,10 @@ function $$(node) {
recentDbs.sort();
$.each(recentDbs, function(idx, name) {
if (name) {
+ name = encodeURIComponent(name);
$("#dbs").append("<li>" +
"<button class='remove' title='Remove from list' value='" + name + "'></button>" +
- "<a href='database.html?" + encodeURIComponent(name) + "' title='" + name + "'>" + name +
+ "<a href='database.html?" + name + "' title='" + name + "'>" + name +
"</a></li>");
}
});
@@ -334,6 +335,14 @@ function $$(node) {
return callback(decl);
}
+ function windowName() {
+ try {
+ return JSON.parse(window.name || "{}");
+ } catch (e) {
+ return {};
+ }
+ }
+
// add suffix to cookie names to be able to separate between ports
var cookiePrefix = location.port + "_";
@@ -366,15 +375,15 @@ function $$(node) {
"window": {
get: function(name) {
- return JSON.parse(window.name || "{}")[name];
+ return windowName()[name];
},
set: function(name, value) {
- var obj = JSON.parse(window.name || "{}");
+ var obj = windowName();
obj[name] = value || null;
window.name = JSON.stringify(obj);
},
del: function(name) {
- var obj = JSON.parse(window.name || "{}");
+ var obj = windowName();
delete obj[name];
window.name = JSON.stringify(obj);
}
diff --git a/rel/overlay/share/www/script/jquery.couch.js b/rel/overlay/share/www/script/jquery.couch.js
index ebf7d52a..114e5801 100644
--- a/rel/overlay/share/www/script/jquery.couch.js
+++ b/rel/overlay/share/www/script/jquery.couch.js
@@ -36,7 +36,7 @@
}
user_doc.type = "user";
if (!user_doc.roles) {
- user_doc.roles = []
+ user_doc.roles = [];
}
return user_doc;
};
@@ -75,7 +75,7 @@
req.type = "PUT";
req.data = toJSON(value);
req.contentType = "application/json";
- req.processData = false
+ req.processData = false;
}
ajax(req, options,
@@ -115,7 +115,7 @@
user_doc = prepareUserDoc(user_doc, password);
$.couch.userDb(function(db) {
db.saveDoc(user_doc, options);
- })
+ });
},
login: function(options) {
@@ -167,7 +167,7 @@
doc._attachments["rev-"+doc._rev.split("-")[0]] = {
content_type :"application/json",
data : Base64.encode(rawDocs[doc._id].raw)
- }
+ };
return true;
}
}
@@ -583,7 +583,7 @@
if (!uuidCache.length) {
ajax({url: this.urlPrefix + "/_uuids", data: {count: cacheNum}, async: false}, {
success: function(resp) {
- uuidCache = resp.uuids
+ uuidCache = resp.uuids;
}
},
"Failed to retrieve UUID batch."
diff --git a/rel/overlay/share/www/script/test/attachment_names.js b/rel/overlay/share/www/script/test/attachment_names.js
index d90c24c4..988dd2d2 100644
--- a/rel/overlay/share/www/script/test/attachment_names.js
+++ b/rel/overlay/share/www/script/test/attachment_names.js
@@ -24,7 +24,7 @@ couchTests.attachment_names = function(debug) {
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
- }
+ };
// inline attachments
try {
@@ -72,7 +72,7 @@ couchTests.attachment_names = function(debug) {
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
- }
+ };
try {
db.save(binAttDoc);
diff --git a/rel/overlay/share/www/script/test/attachment_paths.js b/rel/overlay/share/www/script/test/attachment_paths.js
index a2a0f69c..3f6ffb7c 100644
--- a/rel/overlay/share/www/script/test/attachment_paths.js
+++ b/rel/overlay/share/www/script/test/attachment_paths.js
@@ -33,7 +33,7 @@ couchTests.attachment_paths = function(debug) {
data: "V2UgbGlrZSBwZXJjZW50IHR3byBGLg=="
}
}
- }
+ };
T(db.save(binAttDoc).ok);
@@ -73,7 +73,10 @@ couchTests.attachment_paths = function(debug) {
T(binAttDoc._attachments["foo/bar.txt"] !== undefined);
T(binAttDoc._attachments["foo%2Fbaz.txt"] !== undefined);
T(binAttDoc._attachments["foo/bar2.txt"] !== undefined);
- T(binAttDoc._attachments["foo/bar2.txt"].content_type == "text/plain;charset=utf-8");
+ TEquals("text/plain;charset=utf-8", // thank you Safari
+ binAttDoc._attachments["foo/bar2.txt"].content_type.toLowerCase(),
+ "correct content-type"
+ );
T(binAttDoc._attachments["foo/bar2.txt"].length == 30);
//// now repeat the while thing with a design doc
@@ -92,7 +95,7 @@ couchTests.attachment_paths = function(debug) {
data: "V2UgbGlrZSBwZXJjZW50IHR3byBGLg=="
}
}
- }
+ };
T(db.save(binAttDoc).ok);
@@ -141,7 +144,10 @@ couchTests.attachment_paths = function(debug) {
T(binAttDoc._attachments["foo/bar.txt"] !== undefined);
T(binAttDoc._attachments["foo/bar2.txt"] !== undefined);
- T(binAttDoc._attachments["foo/bar2.txt"].content_type == "text/plain;charset=utf-8");
+ TEquals("text/plain;charset=utf-8", // thank you Safari
+ binAttDoc._attachments["foo/bar2.txt"].content_type.toLowerCase(),
+ "correct content-type"
+ );
T(binAttDoc._attachments["foo/bar2.txt"].length == 30);
}
};
diff --git a/rel/overlay/share/www/script/test/attachment_views.js b/rel/overlay/share/www/script/test/attachment_views.js
index fd30dcfc..a92a8ad0 100644
--- a/rel/overlay/share/www/script/test/attachment_views.js
+++ b/rel/overlay/share/www/script/test/attachment_views.js
@@ -68,11 +68,11 @@ couchTests.attachment_views= function(debug) {
}
emit(parseInt(doc._id), count);
- }
+ };
var reduceFunction = function(key, values) {
return sum(values);
- }
+ };
var result = db.query(mapFunction, reduceFunction);
diff --git a/rel/overlay/share/www/script/test/attachments.js b/rel/overlay/share/www/script/test/attachments.js
index 9d89d5d0..e16c384f 100644
--- a/rel/overlay/share/www/script/test/attachments.js
+++ b/rel/overlay/share/www/script/test/attachments.js
@@ -24,7 +24,7 @@ couchTests.attachments= function(debug) {
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
- }
+ };
var save_response = db.save(binAttDoc);
T(save_response.ok);
@@ -43,7 +43,7 @@ couchTests.attachments= function(debug) {
data: ""
}
}
- }
+ };
T(db.save(binAttDoc2).ok);
@@ -68,12 +68,12 @@ couchTests.attachments= function(debug) {
T(binAttDoc2._attachments["foo.txt"] !== undefined);
T(binAttDoc2._attachments["foo2.txt"] !== undefined);
- T(binAttDoc2._attachments["foo2.txt"].content_type == "text/plain;charset=utf-8");
+ TEqualsIgnoreCase("text/plain;charset=utf-8", binAttDoc2._attachments["foo2.txt"].content_type);
T(binAttDoc2._attachments["foo2.txt"].length == 30);
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc2/foo2.txt");
T(xhr.responseText == "This is no base64 encoded text");
- T(xhr.getResponseHeader("Content-Type") == "text/plain;charset=utf-8");
+ TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
// test without rev, should fail
var xhr = CouchDB.request("DELETE", "/test_suite_db/bin_doc2/foo2.txt");
@@ -96,7 +96,7 @@ couchTests.attachments= function(debug) {
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc3/attachment.txt");
T(xhr.responseText == bin_data);
- T(xhr.getResponseHeader("Content-Type") == "text/plain;charset=utf-8");
+ TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
var xhr = CouchDB.request("PUT", "/test_suite_db/bin_doc3/attachment.txt", {
headers:{"Content-Type":"text/plain;charset=utf-8"},
@@ -113,11 +113,11 @@ couchTests.attachments= function(debug) {
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc3/attachment.txt");
T(xhr.responseText == bin_data);
- T(xhr.getResponseHeader("Content-Type") == "text/plain;charset=utf-8");
+ TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc3/attachment.txt?rev=" + rev);
T(xhr.responseText == bin_data);
- T(xhr.getResponseHeader("Content-Type") == "text/plain;charset=utf-8");
+ TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
var xhr = CouchDB.request("DELETE", "/test_suite_db/bin_doc3/attachment.txt?rev=" + rev);
T(xhr.status == 200);
@@ -129,7 +129,7 @@ couchTests.attachments= function(debug) {
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc3/attachment.txt?rev=" + rev);
T(xhr.status == 200);
T(xhr.responseText == bin_data);
- T(xhr.getResponseHeader("Content-Type") == "text/plain;charset=utf-8");
+ TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
// empty attachments
var xhr = CouchDB.request("PUT", "/test_suite_db/bin_doc4/attachment.txt", {
@@ -156,7 +156,7 @@ couchTests.attachments= function(debug) {
// Attachment sparseness COUCHDB-220
- var docs = []
+ var docs = [];
for (var i = 0; i < 5; i++) {
var doc = {
_id: (i).toString(),
@@ -166,8 +166,8 @@ couchTests.attachments= function(debug) {
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
- }
- docs.push(doc)
+ };
+ docs.push(doc);
}
var saved = db.bulkSave(docs);
@@ -210,7 +210,7 @@ couchTests.attachments= function(debug) {
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc5/lorem.txt");
T(xhr.responseText == lorem);
- T(xhr.getResponseHeader("Content-Type") == "text/plain;charset=utf-8");
+ TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
// test large inline attachment too
var lorem_b64 = CouchDB.request("GET", "/_utils/script/test/lorem_b64.txt").responseText;
@@ -254,7 +254,7 @@ couchTests.attachments= function(debug) {
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
- }
+ };
T(db.save(bin_doc6).ok);
// stub out the attachment
bin_doc6._attachments["foo.txt"] = { stub: true };
@@ -268,6 +268,6 @@ couchTests.attachments= function(debug) {
T(db.save(bin_doc6).ok == true);
T(false && "Shouldn't get here!");
} catch (e) {
- T(e.error == "missing_stub")
+ T(e.error == "missing_stub");
}
};
diff --git a/rel/overlay/share/www/script/test/attachments_multipart.js b/rel/overlay/share/www/script/test/attachments_multipart.js
index 2b79e559..f173d2bb 100644
--- a/rel/overlay/share/www/script/test/attachments_multipart.js
+++ b/rel/overlay/share/www/script/test/attachments_multipart.js
@@ -29,17 +29,17 @@ couchTests.attachments_multipart= function(debug) {
"_attachments":{
"foo.txt": {
"follows":true,
- "content_type":"text/plain",
+ "content_type":"application/test",
"length":21
},
"bar.txt": {
"follows":true,
- "content_type":"text/plain",
+ "content_type":"application/test",
"length":20
},
"baz.txt": {
"follows":true,
- "content_type":"text/plain",
+ "content_type":"application/test",
"length":19
}
}
@@ -58,7 +58,7 @@ couchTests.attachments_multipart= function(debug) {
var result = JSON.parse(xhr.responseText);
- T(result.ok)
+ T(result.ok);
@@ -193,7 +193,7 @@ couchTests.attachments_multipart= function(debug) {
// a certain rev).
xhr = CouchDB.request("GET", "/test_suite_db/multipart?atts_since=[\"" + firstrev + "\"]",
- {headers:{"accept": "multipart/related,*/*;"}});
+ {headers:{"accept": "multipart/related, */*"}});
T(xhr.status == 200);
diff --git a/rel/overlay/share/www/script/test/auth_cache.js b/rel/overlay/share/www/script/test/auth_cache.js
index 75827dbd..e48f7370 100644
--- a/rel/overlay/share/www/script/test/auth_cache.js
+++ b/rel/overlay/share/www/script/test/auth_cache.js
@@ -238,6 +238,37 @@ couchTests.auth_cache = function(debug) {
T(misses_after === misses_before);
T(hits_after === (hits_before + 1));
+
+ // login, compact authentication DB, login again and verify that
+ // there was a cache hit
+ hits_before = hits_after;
+ misses_before = misses_after;
+
+ T(CouchDB.login("johndoe", "123456").ok);
+
+ hits_after = hits();
+ misses_after = misses();
+
+ T(misses_after === (misses_before + 1));
+ T(hits_after === hits_before);
+
+ T(CouchDB.logout().ok);
+ T(authDb.compact().ok);
+
+ while (authDb.info().compact_running);
+
+ hits_before = hits_after;
+ misses_before = misses_after;
+
+ T(CouchDB.login("johndoe", "123456").ok);
+
+ hits_after = hits();
+ misses_after = misses();
+
+ T(misses_after === misses_before);
+ T(hits_after === (hits_before + 1));
+
+ T(CouchDB.logout().ok);
}
diff --git a/rel/overlay/share/www/script/test/basics.js b/rel/overlay/share/www/script/test/basics.js
index 6a3ae471..8885ba6e 100644
--- a/rel/overlay/share/www/script/test/basics.js
+++ b/rel/overlay/share/www/script/test/basics.js
@@ -45,7 +45,7 @@ couchTests.basics = function(debug) {
// Get the database info, check the db_name
T(db.info().db_name == "test_suite_db");
- T(CouchDB.allDbs().indexOf("test_suite_db") != -1)
+ T(CouchDB.allDbs().indexOf("test_suite_db") != -1);
// Get the database info, check the doc_count
T(db.info().doc_count == 0);
@@ -91,13 +91,13 @@ couchTests.basics = function(debug) {
emit(null, doc.b);
};
- results = db.query(mapFunction);
+ var results = db.query(mapFunction);
// verify only one document found and the result value (doc.b).
T(results.total_rows == 1 && results.rows[0].value == 16);
// reopen document we saved earlier
- existingDoc = db.open(id);
+ var existingDoc = db.open(id);
T(existingDoc.a==1);
@@ -191,12 +191,12 @@ couchTests.basics = function(debug) {
T(xhr.status == 404);
// Check for invalid document members
- bad_docs = [
+ var bad_docs = [
["goldfish", {"_zing": 4}],
["zebrafish", {"_zoom": "hello"}],
["mudfish", {"zane": "goldfish", "_fan": "something smells delicious"}],
["tastyfish", {"_bing": {"wha?": "soda can"}}]
- ]
+ ];
var test_doc = function(info) {
var data = JSON.stringify(info[1]);
xhr = CouchDB.request("PUT", "/test_suite_db/" + info[0], {body: data});
diff --git a/rel/overlay/share/www/script/test/bulk_docs.js b/rel/overlay/share/www/script/test/bulk_docs.js
index 346aea83..9095e6b3 100644
--- a/rel/overlay/share/www/script/test/bulk_docs.js
+++ b/rel/overlay/share/www/script/test/bulk_docs.js
@@ -51,12 +51,12 @@ couchTests.bulk_docs = function(debug) {
T(results.length == 5);
T(results[0].id == "0");
T(results[0].error == "conflict");
- T(results[0].rev === undefined); // no rev member when a conflict
+ T(typeof results[0].rev === "undefined"); // no rev member when a conflict
// but the rest are not
for (i = 1; i < 5; i++) {
T(results[i].id == i.toString());
- T(results[i].rev)
+ T(results[i].rev);
T(db.open(docs[i]._id) == null);
}
@@ -64,7 +64,7 @@ couchTests.bulk_docs = function(debug) {
// save doc 0, this will cause a conflict when we save docs[0]
var doc = db.open("0");
- docs[0] = db.open("0")
+ docs[0] = db.open("0");
db.save(doc);
docs[0].shooby = "dooby";
@@ -93,8 +93,8 @@ couchTests.bulk_docs = function(debug) {
// Regression test for failure on update/delete
var newdoc = {"_id": "foobar", "body": "baz"};
T(db.save(newdoc).ok);
- update = {"_id": newdoc._id, "_rev": newdoc._rev, "body": "blam"};
- torem = {"_id": newdoc._id, "_rev": newdoc._rev, "_deleted": true};
+ var update = {"_id": newdoc._id, "_rev": newdoc._rev, "body": "blam"};
+ var torem = {"_id": newdoc._id, "_rev": newdoc._rev, "_deleted": true};
results = db.bulkSave([update, torem]);
T(results[0].error == "conflict" || results[1].error == "conflict");
};
diff --git a/rel/overlay/share/www/script/test/compact.js b/rel/overlay/share/www/script/test/compact.js
index 22eeaec1..805a3b08 100644
--- a/rel/overlay/share/www/script/test/compact.js
+++ b/rel/overlay/share/www/script/test/compact.js
@@ -26,7 +26,7 @@ couchTests.compact = function(debug) {
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
- }
+ };
T(db.save(binAttDoc).ok);
@@ -51,8 +51,8 @@ couchTests.compact = function(debug) {
T(db.ensureFullCommit().ok);
restartServer();
var xhr = CouchDB.request("GET", "/test_suite_db/bin_doc/foo.txt");
- T(xhr.responseText == "This is a base64 encoded text")
- T(xhr.getResponseHeader("Content-Type") == "text/plain")
+ T(xhr.responseText == "This is a base64 encoded text");
+ T(xhr.getResponseHeader("Content-Type") == "text/plain");
T(db.info().doc_count == 1);
T(db.info().disk_size < deletesize);
diff --git a/rel/overlay/share/www/script/test/conflicts.js b/rel/overlay/share/www/script/test/conflicts.js
index b8b93946..7258bc31 100644
--- a/rel/overlay/share/www/script/test/conflicts.js
+++ b/rel/overlay/share/www/script/test/conflicts.js
@@ -44,7 +44,7 @@ couchTests.conflicts = function(debug) {
var changes = db.changes();
- T( changes.results.length == 1)
+ T(changes.results.length == 1);
// Now clear out the _rev member and save. This indicates this document is
// new, not based on an existing revision.
diff --git a/rel/overlay/share/www/script/test/cookie_auth.js b/rel/overlay/share/www/script/test/cookie_auth.js
index 68ec882d..ef915602 100644
--- a/rel/overlay/share/www/script/test/cookie_auth.js
+++ b/rel/overlay/share/www/script/test/cookie_auth.js
@@ -65,7 +65,7 @@ couchTests.cookie_auth = function(debug) {
}, "eh, Boo-Boo?");
try {
- usersDb.save(duplicateJchrisDoc)
+ usersDb.save(duplicateJchrisDoc);
T(false && "Can't create duplicate user names. Should have thrown an error.");
} catch (e) {
T(e.error == "conflict");
@@ -78,7 +78,7 @@ couchTests.cookie_auth = function(debug) {
}, "copperfield");
try {
- usersDb.save(underscoreUserDoc)
+ usersDb.save(underscoreUserDoc);
T(false && "Can't create underscore user names. Should have thrown an error.");
} catch (e) {
T(e.error == "forbidden");
@@ -93,7 +93,7 @@ couchTests.cookie_auth = function(debug) {
badIdDoc._id = "org.apache.couchdb:w00x";
try {
- usersDb.save(badIdDoc)
+ usersDb.save(badIdDoc);
T(false && "Can't create malformed docids. Should have thrown an error.");
} catch (e) {
T(e.error == "forbidden");
@@ -125,7 +125,7 @@ couchTests.cookie_auth = function(debug) {
T(CouchDB.session().userCtx.name != 'Jason Davies');
// test redirect
- xhr = CouchDB.request("POST", "/_session?next=/", {
+ var xhr = CouchDB.request("POST", "/_session?next=/", {
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: "name=Jason%20Davies&password="+encodeURIComponent(password)
});
@@ -135,10 +135,10 @@ couchTests.cookie_auth = function(debug) {
// to follow the redirect, ie, the browser follows and does a
// GET on the returned Location
if (xhr.status == 200) {
- T(/Welcome/.test(xhr.responseText))
+ T(/Welcome/.test(xhr.responseText));
} else {
- T(xhr.status == 302)
- T(xhr.getResponseHeader("Location"))
+ T(xhr.status == 302);
+ T(xhr.getResponseHeader("Location"));
}
// test users db validations
@@ -151,7 +151,7 @@ couchTests.cookie_auth = function(debug) {
jasonUserDoc.foo=3;
try {
- usersDb.save(jasonUserDoc)
+ usersDb.save(jasonUserDoc);
T(false && "Can't update someone else's user doc. Should have thrown an error.");
} catch (e) {
T(e.error == "forbidden");
@@ -162,7 +162,7 @@ couchTests.cookie_auth = function(debug) {
jchrisUserDoc.roles = ["foo"];
try {
- usersDb.save(jchrisUserDoc)
+ usersDb.save(jchrisUserDoc);
T(false && "Can't set roles unless you are admin. Should have thrown an error.");
} catch (e) {
T(e.error == "forbidden");
@@ -179,7 +179,7 @@ couchTests.cookie_auth = function(debug) {
jchrisUserDoc.roles = ["_bar"];
try {
- usersDb.save(jchrisUserDoc)
+ usersDb.save(jchrisUserDoc);
T(false && "Can't add system roles to user's db. Should have thrown an error.");
} catch (e) {
T(e.error == "forbidden");
diff --git a/rel/overlay/share/www/script/test/design_docs.js b/rel/overlay/share/www/script/test/design_docs.js
index e62951ac..a24167b2 100644
--- a/rel/overlay/share/www/script/test/design_docs.js
+++ b/rel/overlay/share/www/script/test/design_docs.js
@@ -41,8 +41,8 @@ function() {
whatever : {
stringzone : "exports.string = 'plankton';",
commonjs : {
- whynot : "exports.test = require('../stringzone')",
- upper : "exports.testing = require('./whynot').test.string.toUpperCase()+module.id"
+ whynot : "exports.test = require('../stringzone'); exports.foo = require('whatever/stringzone');",
+ upper : "exports.testing = require('./whynot').test.string.toUpperCase()+module.id+require('./whynot').foo.string"
}
},
views: {
@@ -58,7 +58,8 @@ function() {
},
shows: {
simple: "function() {return 'ok'};",
- requirey : "function() { var lib = require('whatever/commonjs/upper'); return lib.testing; };"
+ requirey : "function() { var lib = require('whatever/commonjs/upper'); return lib.testing; };",
+ circular : "function() { var lib = require('whatever/commonjs/upper'); return JSON.stringify(this); };"
}
};
@@ -86,7 +87,15 @@ function() {
// test commonjs require
var xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/requirey");
T(xhr.status == 200);
- TEquals("PLANKTONwhatever/commonjs/upper", xhr.responseText);
+ TEquals("PLANKTONwhatever/commonjs/upperplankton", xhr.responseText);
+
+ var xhr = CouchDB.request("GET", "/test_suite_db/_design/test/_show/circular");
+ T(xhr.status == 200);
+ TEquals("javascript", JSON.parse(xhr.responseText).language);
+
+ var prev_view_sig = db.designInfo("_design/test").view_index.signature;
+
+ db.bulkSave(makeDocs(1, numDocs + 1));
// test that we get design doc info back
var dinfo = db.designInfo("_design/test");
@@ -94,9 +103,27 @@ function() {
var vinfo = dinfo.view_index;
TEquals(51, vinfo.disk_size);
TEquals(false, vinfo.compact_running);
- TEquals("3f88e53b303e2342e49a66c538c30679", vinfo.signature);
+ // test that GET /db/_design/test/_info
+ // hasn't triggered an update of the views
+ TEquals(prev_view_sig, vinfo.signature, 'ddoc sig');
+ for (var loop = 0; loop < 2; loop++) {
+ T(db.view("test/all_docs_twice", {stale: "ok"}).total_rows === 0);
+ T(db.view("test/single_doc", {stale: "ok"}).total_rows === 0);
+ T(db.view("test/summate", {stale: "ok"}).rows.length === 0);
+ T(db.ensureFullCommit().ok);
+ restartServer();
+ };
- db.bulkSave(makeDocs(1, numDocs + 1));
+ // test that POST /db/_view_cleanup
+ // doesn't trigger an update of the views
+ T(db.viewCleanup().ok);
+ for (var loop = 0; loop < 2; loop++) {
+ T(db.view("test/all_docs_twice", {stale: "ok"}).total_rows == 0);
+ T(db.view("test/single_doc", {stale: "ok"}).total_rows == 0);
+ T(db.view("test/summate", {stale: "ok"}).rows.length == 0);
+ T(db.ensureFullCommit().ok);
+ restartServer();
+ };
// test that the _all_docs view returns correctly with keys
var results = db.allDocs({startkey:"_design", endkey:"_design0"});
@@ -107,9 +134,9 @@ function() {
for (var i = 0; i < numDocs; i++) {
T(rows[2*i].key == i+1);
T(rows[(2*i)+1].key == i+1);
- }
- T(db.view("test/no_docs").total_rows == 0)
- T(db.view("test/single_doc").total_rows == 1)
+ };
+ T(db.view("test/no_docs").total_rows == 0);
+ T(db.view("test/single_doc").total_rows == 1);
T(db.ensureFullCommit().ok);
restartServer();
};
diff --git a/rel/overlay/share/www/script/test/erlang_views.js b/rel/overlay/share/www/script/test/erlang_views.js
index 5e93cb96..7eddab40 100644
--- a/rel/overlay/share/www/script/test/erlang_views.js
+++ b/rel/overlay/share/www/script/test/erlang_views.js
@@ -44,7 +44,7 @@ couchTests.erlang_views = function(debug) {
// check simple reduction - another doc with same key.
var doc = {_id: "2", integer: 1, string: "str2"};
T(db.save(doc).ok);
- rfun = "fun(Keys, Values, ReReduce) -> length(Values) end."
+ rfun = "fun(Keys, Values, ReReduce) -> length(Values) end.";
results = db.query(mfun, rfun, null, null, "erlang");
T(results.rows[0].value == 2);
diff --git a/rel/overlay/share/www/script/test/etags_views.js b/rel/overlay/share/www/script/test/etags_views.js
index a12734f8..7e1537bd 100644
--- a/rel/overlay/share/www/script/test/etags_views.js
+++ b/rel/overlay/share/www/script/test/etags_views.js
@@ -38,7 +38,7 @@ couchTests.etags_views = function(debug) {
})
}
}
- }
+ };
T(db.save(designDoc).ok);
var xhr;
var docs = makeDocs(0, 10);
diff --git a/rel/overlay/share/www/script/test/list_views.js b/rel/overlay/share/www/script/test/list_views.js
index f826b46f..44afa899 100644
--- a/rel/overlay/share/www/script/test/list_views.js
+++ b/rel/overlay/share/www/script/test/list_views.js
@@ -394,7 +394,7 @@ couchTests.list_views = function(debug) {
T(/LastKey: 0/.test(xhr.responseText));
// Test we do multi-key requests on lists and views in separate docs.
- var url = "/test_suite_db/_design/lists/_list/simpleForm/views/basicView"
+ var url = "/test_suite_db/_design/lists/_list/simpleForm/views/basicView";
xhr = CouchDB.request("POST", url, {
body: '{"keys":[-2,-4,-5,-7]}'
});
diff --git a/rel/overlay/share/www/script/test/method_override.js b/rel/overlay/share/www/script/test/method_override.js
index 26e9bee0..0bb4c61f 100644
--- a/rel/overlay/share/www/script/test/method_override.js
+++ b/rel/overlay/share/www/script/test/method_override.js
@@ -28,7 +28,7 @@ couchTests.method_override = function(debug) {
T(doc.bob == "connie");
xhr = CouchDB.request("POST", "/test_suite_db/fnord?rev=" + doc._rev, {headers:{"X-HTTP-Method-Override" : "DELETE"}});
- T(xhr.status == 200)
+ T(xhr.status == 200);
xhr = CouchDB.request("GET", "/test_suite_db/fnord2", {body: JSON.stringify(doc), headers:{"X-HTTP-Method-Override" : "PUT"}});
// Method Override is ignored when original Method isn't POST
diff --git a/rel/overlay/share/www/script/test/proxyauth.js b/rel/overlay/share/www/script/test/proxyauth.js
index 171eef37..91e2f221 100644
--- a/rel/overlay/share/www/script/test/proxyauth.js
+++ b/rel/overlay/share/www/script/test/proxyauth.js
@@ -39,7 +39,7 @@ couchTests.proxyauth = function(debug) {
db.createDb();
var benoitcUserDoc = CouchDB.prepareUserDoc({
- name: "benoitc@apache.org",
+ name: "benoitc@apache.org"
}, "test");
T(usersDb.save(benoitcUserDoc).ok);
@@ -56,7 +56,7 @@ couchTests.proxyauth = function(debug) {
CouchDB.logout();
- headers = {
+ var headers = {
"X-Auth-CouchDB-UserName": "benoitc@apache.org",
"X-Auth-CouchDB-Roles": "test",
"X-Auth-CouchDB-Token": hex_hmac_sha1(secret, "benoitc@apache.org")
@@ -72,14 +72,13 @@ couchTests.proxyauth = function(debug) {
}),
"role": stringFun(function(doc, req) {
return req.userCtx['roles'][0];
- }),
+ })
}
-
- }
+ };
db.save(designDoc);
- req = CouchDB.request("GET", "/test_suite_db/_design/test/_show/welcome",
+ var req = CouchDB.request("GET", "/test_suite_db/_design/test/_show/welcome",
{headers: headers});
T(req.responseText == "Welcome benoitc@apache.org");
@@ -87,7 +86,7 @@ couchTests.proxyauth = function(debug) {
{headers: headers});
T(req.responseText == "test");
- xhr = CouchDB.request("PUT", "/_config/couch_httpd_auth/proxy_use_secret",{
+ var xhr = CouchDB.request("PUT", "/_config/couch_httpd_auth/proxy_use_secret",{
body : JSON.stringify("true"),
headers: {"X-Couch-Persist": "false"}
});
diff --git a/rel/overlay/share/www/script/test/purge.js b/rel/overlay/share/www/script/test/purge.js
index a924c348..f8f45138 100644
--- a/rel/overlay/share/www/script/test/purge.js
+++ b/rel/overlay/share/www/script/test/purge.js
@@ -30,7 +30,7 @@ couchTests.purge = function(debug) {
all_docs_twice: {map: "function(doc) { emit(doc.integer, null); emit(doc.integer, null) }"},
single_doc: {map: "function(doc) { if (doc._id == \"1\") { emit(1, null) }}"}
}
- }
+ };
T(db.save(designDoc).ok);
@@ -50,7 +50,7 @@ couchTests.purge = function(debug) {
// purge the documents
var xhr = CouchDB.request("POST", "/test_suite_db/_purge", {
- body: JSON.stringify({"1":[doc1._rev], "2":[doc2._rev]}),
+ body: JSON.stringify({"1":[doc1._rev], "2":[doc2._rev]})
});
T(xhr.status == 200);
@@ -76,6 +76,14 @@ couchTests.purge = function(debug) {
}
T(db.view("test/single_doc").total_rows == 0);
+ // purge sequences are preserved after compaction (COUCHDB-1021)
+ T(db.compact().ok);
+ T(db.last_req.status == 202);
+ // compaction isn't instantaneous, loop until done
+ while (db.info().compact_running) {};
+ var compactInfo = db.info();
+ T(compactInfo.purge_seq == newInfo.purge_seq);
+
// purge documents twice in a row without loading views
// (causes full view rebuilds)
@@ -83,13 +91,13 @@ couchTests.purge = function(debug) {
var doc4 = db.open("4");
xhr = CouchDB.request("POST", "/test_suite_db/_purge", {
- body: JSON.stringify({"3":[doc3._rev]}),
+ body: JSON.stringify({"3":[doc3._rev]})
});
T(xhr.status == 200);
xhr = CouchDB.request("POST", "/test_suite_db/_purge", {
- body: JSON.stringify({"4":[doc4._rev]}),
+ body: JSON.stringify({"4":[doc4._rev]})
});
T(xhr.status == 200);
diff --git a/rel/overlay/share/www/script/test/recreate_doc.js b/rel/overlay/share/www/script/test/recreate_doc.js
index a6a64ac0..05843558 100644
--- a/rel/overlay/share/www/script/test/recreate_doc.js
+++ b/rel/overlay/share/www/script/test/recreate_doc.js
@@ -51,7 +51,7 @@ couchTests.recreate_doc = function(debug) {
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
}
- }
+ };
try {
// same as before, but with binary
db.save(binAttDoc);
diff --git a/rel/overlay/share/www/script/test/reduce.js b/rel/overlay/share/www/script/test/reduce.js
index 9c80fa7f..979a0292 100644
--- a/rel/overlay/share/www/script/test/reduce.js
+++ b/rel/overlay/share/www/script/test/reduce.js
@@ -15,14 +15,15 @@ couchTests.reduce = function(debug) {
db.deleteDb();
db.createDb();
if (debug) debugger;
- var numDocs = 500
+ var numDocs = 500;
var docs = makeDocs(1,numDocs + 1);
db.bulkSave(docs);
var summate = function(N) {return (N+1)*N/2;};
var map = function (doc) {
emit(doc.integer, doc.integer);
- emit(doc.integer, doc.integer)};
+ emit(doc.integer, doc.integer);
+ };
var reduce = function (keys, values) { return sum(values); };
var result = db.query(map, reduce);
T(result.rows[0].value == 2*summate(numDocs));
@@ -69,7 +70,7 @@ couchTests.reduce = function(debug) {
T(db.info().doc_count == ((i - 1) * 10 * 11) + ((j + 1) * 11));
}
- map = function (doc) {emit(doc.keys, 1)};
+ map = function (doc) { emit(doc.keys, 1); };
reduce = function (keys, values) { return sum(values); };
var results = db.query(map, reduce, {group:true});
@@ -107,7 +108,7 @@ couchTests.reduce = function(debug) {
db.createDb();
- var map = function (doc) {emit(doc.val, doc.val)};
+ var map = function (doc) { emit(doc.val, doc.val); };
var reduceCombine = function (keys, values, rereduce) {
// This computes the standard deviation of the mapped results
var stdDeviation=0.0;
diff --git a/rel/overlay/share/www/script/test/reduce_builtin.js b/rel/overlay/share/www/script/test/reduce_builtin.js
index d9635688..c9d41fa4 100644
--- a/rel/overlay/share/www/script/test/reduce_builtin.js
+++ b/rel/overlay/share/www/script/test/reduce_builtin.js
@@ -16,7 +16,7 @@ couchTests.reduce_builtin = function(debug) {
db.createDb();
if (debug) debugger;
- var numDocs = 500
+ var numDocs = 500;
var docs = makeDocs(1,numDocs + 1);
db.bulkSave(docs);
@@ -28,13 +28,14 @@ couchTests.reduce_builtin = function(debug) {
acc += i*i;
}
return acc;
- }
+ };
// this is the same test as the reduce.js test
// only we'll let CouchDB run reduce in Erlang
var map = function (doc) {
emit(doc.integer, doc.integer);
- emit(doc.integer, doc.integer)};
+ emit(doc.integer, doc.integer);
+ };
var result = db.query(map, "_sum");
T(result.rows[0].value == 2*summate(numDocs));
@@ -115,7 +116,7 @@ couchTests.reduce_builtin = function(debug) {
T(db.info().doc_count == ((i - 1) * 10 * 11) + ((j + 1) * 11));
}
- map = function (doc) {emit(doc.keys, 1)};
+ map = function (doc) { emit(doc.keys, 1); };
// with emitted values being 1, count should be the same as sum
var builtins = ["_sum", "_count"];
diff --git a/rel/overlay/share/www/script/test/replication.js b/rel/overlay/share/www/script/test/replication.js
index d2b3164b..7cc1f823 100644
--- a/rel/overlay/share/www/script/test/replication.js
+++ b/rel/overlay/share/www/script/test/replication.js
@@ -22,14 +22,14 @@ couchTests.replication = function(debug) {
target:"test_suite_db_b"},
{source:"http://" + host + "/test_suite_db_a",
target:"http://" + host + "/test_suite_db_b"}
- ]
+ ];
var dbA = new CouchDB("test_suite_db_a", {"X-Couch-Full-Commit":"false"});
var dbB = new CouchDB("test_suite_db_b", {"X-Couch-Full-Commit":"false"});
var numDocs = 10;
var xhr;
for (var testPair = 0; testPair < dbPairs.length; testPair++) {
- var A = dbPairs[testPair].source
- var B = dbPairs[testPair].target
+ var A = dbPairs[testPair].source;
+ var B = dbPairs[testPair].target;
dbA.deleteDb();
dbA.createDb();
@@ -41,7 +41,7 @@ couchTests.replication = function(debug) {
test_template: new function () {
this.init = function(dbA, dbB) {
// before anything has happened
- }
+ };
this.afterAB1 = function(dbA, dbB) {
// called after replicating src=A tgt=B first time.
};
@@ -165,20 +165,20 @@ couchTests.replication = function(debug) {
this.afterAB1 = function(dbA, dbB) {
var xhr = CouchDB.request("GET",
"/test_suite_db_a/bin_doc/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
xhr = CouchDB.request("GET",
"/test_suite_db_b/bin_doc/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
// and the design-doc
xhr = CouchDB.request("GET",
"/test_suite_db_a/_design/with_bin/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
xhr = CouchDB.request("GET",
"/test_suite_db_b/_design/with_bin/foo%2Bbar.txt");
- T(xhr.responseText == "This is a base64 encoded text")
+ T(xhr.responseText == "This is a base64 encoded text");
};
},
@@ -209,8 +209,8 @@ couchTests.replication = function(debug) {
var docB = dbB.open("foo", {conflicts: true, deleted_conflicts: true});
// We should have no conflicts this time
- T(docA._conflicts === undefined)
- T(docB._conflicts === undefined);
+ T(typeof docA._conflicts === "undefined");
+ T(typeof docB._conflicts === "undefined");
// They show up as deleted conflicts instead
T(docA._deleted_conflicts[0] == docB._deleted_conflicts[0]);
@@ -229,7 +229,7 @@ couchTests.replication = function(debug) {
var seqA = result.source_last_seq;
T(0 == result.history[0].start_last_seq);
- T(result.history[1] === undefined)
+ T(typeof result.history[1] === "undefined");
for(test in repTests) {
if(repTests[test].afterAB1) repTests[test].afterAB1(dbA, dbB);
@@ -239,7 +239,7 @@ couchTests.replication = function(debug) {
var seqB = result.source_last_seq;
T(0 == result.history[0].start_last_seq);
- T(result.history[1] === undefined)
+ T(typeof result.history[1] === "undefined");
for(test in repTests) {
if(repTests[test].afterBA1) repTests[test].afterBA1(dbA, dbB);
@@ -252,7 +252,7 @@ couchTests.replication = function(debug) {
T(seqA < result2.source_last_seq);
T(seqA == result2.history[0].start_last_seq);
- T(result2.history[1].end_last_seq == seqA)
+ T(result2.history[1].end_last_seq == seqA);
seqA = result2.source_last_seq;
@@ -260,11 +260,11 @@ couchTests.replication = function(debug) {
if(repTests[test].afterAB2) repTests[test].afterAB2(dbA, dbB);
}
- result = CouchDB.replicate(B, A)
+ result = CouchDB.replicate(B, A);
T(seqB < result.source_last_seq);
T(seqB == result.history[0].start_last_seq);
- T(result.history[1].end_last_seq == seqB)
+ T(result.history[1].end_last_seq == seqB);
seqB = result.source_last_seq;
@@ -306,21 +306,21 @@ couchTests.replication = function(debug) {
var continuousResult = CouchDB.replicate(dbA.name, "test_suite_db_b", {
body: {"continuous": true}
});
- T(continuousResult.ok)
- T(continuousResult._local_id)
+ T(continuousResult.ok);
+ T(continuousResult._local_id);
var cancelResult = CouchDB.replicate(dbA.name, "test_suite_db_b", {
body: {"cancel": true}
});
- T(cancelResult.ok)
- T(continuousResult._local_id == cancelResult._local_id)
+ T(cancelResult.ok);
+ T(continuousResult._local_id == cancelResult._local_id);
try {
var cancelResult2 = CouchDB.replicate(dbA.name, "test_suite_db_b", {
body: {"cancel": true}
});
} catch (e) {
- T(e.error == "not_found")
+ T(e.error == "not_found");
}
// test replication object option doc_ids
@@ -527,4 +527,160 @@ couchTests.replication = function(debug) {
T(docFoo4 === null);
}
+ // test for COUCHDB-868 - design docs' attachments not getting replicated
+ // when doing a pull replication with HTTP basic auth
+ dbA = new CouchDB("test_suite_db_a");
+ dbB = new CouchDB("test_suite_db_b");
+ var usersDb = new CouchDB("test_suite_auth");
+ var lorem = CouchDB.request(
+ "GET", "/_utils/script/test/lorem.txt").responseText;
+ var lorem_b64 = CouchDB.request(
+ "GET", "/_utils/script/test/lorem_b64.txt").responseText;
+
+ usersDb.deleteDb();
+ usersDb.createDb();
+ dbA.deleteDb();
+ dbA.createDb();
+ dbB.deleteDb();
+ dbB.createDb();
+
+ var atts_ddoc = {
+ _id: "_design/i_have_atts",
+ language: "javascript"
+ };
+ T(dbA.save(atts_ddoc).ok);
+
+ var rev = atts_ddoc._rev;
+ var att_1_name = "lorem.txt";
+ var att_2_name = "lorem.dat";
+ var xhr = CouchDB.request(
+ "PUT", "/" + dbA.name + "/" + atts_ddoc._id + "/" + att_1_name + "?rev=" + rev, {
+ headers: {"Content-Type": "text/plain;charset=utf-8"},
+ body: lorem
+ });
+ rev = JSON.parse(xhr.responseText).rev;
+ T(xhr.status === 201);
+ xhr = CouchDB.request(
+ "PUT", "/" + dbA.name + "/" + atts_ddoc._id + "/" + att_2_name + "?rev=" + rev, {
+ headers: {"Content-Type": "application/data"},
+ body: lorem_b64
+ });
+ T(xhr.status === 201);
+
+ var fdmananaUserDoc = CouchDB.prepareUserDoc({
+ name: "fdmanana",
+ roles: ["reader"]
+ }, "qwerty");
+ T(usersDb.save(fdmananaUserDoc).ok);
+
+ T(dbA.setSecObj({
+ admins: {
+ names: [],
+ roles: ["admin"]
+ },
+ readers: {
+ names: [],
+ roles: ["reader"]
+ }
+ }).ok);
+ T(dbB.setSecObj({
+ admins: {
+ names: ["fdmanana"],
+ roles: []
+ }
+ }).ok);
+
+ var server_config = [
+ {
+ section: "couch_httpd_auth",
+ key: "authentication_db",
+ value: usersDb.name
+ },
+ // to prevent admin party mode
+ {
+ section: "admins",
+ key: "joe",
+ value: "erlang"
+ }
+ ];
+
+ var test_fun = function() {
+ T(CouchDB.login("fdmanana", "qwerty").ok);
+ T(CouchDB.session().userCtx.name === "fdmanana");
+ T(CouchDB.session().userCtx.roles.indexOf("_admin") === -1);
+
+ var repResult = CouchDB.replicate(
+ "http://fdmanana:qwerty@" + host + "/" + dbA.name,
+ dbB.name
+ );
+ T(repResult.ok === true);
+ T(repResult.history instanceof Array);
+ T(repResult.history.length === 1);
+ T(repResult.history[0].docs_written === 1);
+ T(repResult.history[0].docs_read === 1);
+ T(repResult.history[0].doc_write_failures === 0);
+
+ var atts_ddoc_copy = dbB.open(atts_ddoc._id);
+ T(atts_ddoc_copy !== null);
+ T(typeof atts_ddoc_copy._attachments === "object");
+ T(atts_ddoc_copy._attachments !== null);
+ T(att_1_name in atts_ddoc_copy._attachments);
+ T(att_2_name in atts_ddoc_copy._attachments);
+
+ var xhr = CouchDB.request("GET", "/" + dbB.name + "/" + atts_ddoc._id + "/" + att_1_name);
+ T(xhr.status === 200);
+ T(xhr.responseText === lorem);
+
+ xhr = CouchDB.request("GET", "/" + dbB.name + "/" + atts_ddoc._id + "/" + att_2_name);
+ T(xhr.status === 200);
+ T(xhr.responseText === lorem_b64);
+
+ CouchDB.logout();
+ T(CouchDB.login("joe", "erlang").ok);
+ T(dbA.setSecObj({
+ admins: {
+ names: [],
+ roles: ["bar"]
+ },
+ readers: {
+ names: [],
+ roles: ["foo"]
+ }
+ }).ok);
+ T(dbB.deleteDb().ok === true);
+ T(dbB.createDb().ok === true);
+ T(dbB.setSecObj({
+ admins: {
+ names: ["fdmanana"],
+ roles: []
+ }
+ }).ok);
+ CouchDB.logout();
+
+ T(CouchDB.login("fdmanana", "qwerty").ok);
+ T(CouchDB.session().userCtx.name === "fdmanana");
+ T(CouchDB.session().userCtx.roles.indexOf("_admin") === -1);
+ try {
+ repResult = CouchDB.replicate(
+ "http://fdmanana:qwerty@" + host + "/" + dbA.name,
+ dbB.name
+ );
+ T(false, "replication should have failed");
+ } catch(x) {
+ T(x.error === "unauthorized");
+ }
+
+ atts_ddoc_copy = dbB.open(atts_ddoc._id);
+ T(atts_ddoc_copy === null);
+
+ CouchDB.logout();
+ T(CouchDB.login("joe", "erlang").ok);
+ };
+
+ run_on_modified_server(server_config, test_fun);
+
+ // cleanup
+ dbA.deleteDb();
+ dbB.deleteDb();
+ usersDb.deleteDb();
};
diff --git a/rel/overlay/share/www/script/test/rewrite.js b/rel/overlay/share/www/script/test/rewrite.js
index 66b33d74..ff2d3822 100644
--- a/rel/overlay/share/www/script/test/rewrite.js
+++ b/rel/overlay/share/www/script/test/rewrite.js
@@ -365,7 +365,16 @@ couchTests.rewrite = function(debug) {
T(result.uuids.length == 1);
var first = result.uuids[0];
});
-
});
-
-} \ No newline at end of file
+
+ // test invalid rewrites
+ // string
+ var ddoc = {
+ _id: "_design/invalid",
+ rewrites: "[{\"from\":\"foo\",\"to\":\"bar\"}]"
+ }
+ db.save(ddoc);
+ var res = CouchDB.request("GET", "/test_suite_db/_design/invalid/_rewrite/foo");
+ TEquals(400, res.status, "should return 400");
+
+}
diff --git a/rel/overlay/share/www/script/test/security_validation.js b/rel/overlay/share/www/script/test/security_validation.js
index e0ab17d6..dd3b202e 100644
--- a/rel/overlay/share/www/script/test/security_validation.js
+++ b/rel/overlay/share/www/script/test/security_validation.js
@@ -136,13 +136,20 @@ couchTests.security_validation = function(debug) {
doc.foo=2;
T(userDb.save(doc).ok);
- // Save a document that's missing an author field.
- try {
- userDb.save({foo:1});
- T(false && "Can't get here. Should have thrown an error 2");
- } catch (e) {
- T(e.error == "forbidden");
- T(userDb.last_req.status == 403);
+ // Save a document that's missing an author field (before and after compaction)
+ for (var i=0; i<2; i++) {
+ try {
+ userDb.save({foo:1});
+ T(false && "Can't get here. Should have thrown an error 2");
+ } catch (e) {
+ T(e.error == "forbidden");
+ T(userDb.last_req.status == 403);
+ }
+ // compact.
+ T(db.compact().ok);
+ T(db.last_req.status == 202);
+ // compaction isn't instantaneous, loop until done
+ while (db.info().compact_running) {};
}
// Now attempt to update the document as a different user, Jan
diff --git a/rel/overlay/share/www/script/test/stats.js b/rel/overlay/share/www/script/test/stats.js
index d2fd6eac..6fb0fbba 100644
--- a/rel/overlay/share/www/script/test/stats.js
+++ b/rel/overlay/share/www/script/test/stats.js
@@ -30,7 +30,7 @@ couchTests.stats = function(debug) {
_id:"_design/test", // turn off couch.js id escaping?
language: "javascript",
views: {
- all_docs: {map: "function(doc) {emit(doc.integer, null);}"},
+ all_docs: {map: "function(doc) {emit(doc.integer, null);}"}
}
};
db.save(designDoc);
@@ -163,12 +163,12 @@ couchTests.stats = function(debug) {
CouchDB.request("POST", "/test_suite_db", {
headers: {"Content-Type": "application/json"},
body: '{"a": "1"}'
- })
+ });
},
test: function(before, after) {
TEquals(before+1, after, "POST'ing new docs increments doc writes.");
}
- })
+ });
runTest("couchdb", "database_writes", {
setup: function(db) {db.save({"_id": "test"});},
@@ -247,7 +247,7 @@ couchTests.stats = function(debug) {
});
runTest("httpd", "temporary_view_reads", {
- run: function(db) {db.query(function(doc) {emit(doc._id)})},
+ run: function(db) { db.query(function(doc) { emit(doc._id); }); },
test: function(before, after) {
TEquals(before+1, after, "Temporary views have their own counter.");
}
@@ -261,7 +261,7 @@ couchTests.stats = function(debug) {
});
runTest("httpd", "view_reads", {
- run: function(db) {db.query(function(doc) {emit(doc._id)});},
+ run: function(db) { db.query(function(doc) { emit(doc._id); }); },
test: function(before, after) {
TEquals(before, after, "Temporary views don't affect permanent views.");
}
diff --git a/rel/overlay/share/www/script/test/users_db.js b/rel/overlay/share/www/script/test/users_db.js
index 667ff3c1..1e13e5d7 100644
--- a/rel/overlay/share/www/script/test/users_db.js
+++ b/rel/overlay/share/www/script/test/users_db.js
@@ -90,6 +90,27 @@ couchTests.users_db = function(debug) {
T(s.name == null);
T(s.roles.indexOf("_admin") !== -1);
T(usersDb.deleteDoc(jchrisWithConflict).ok);
+
+ // you can't change doc from type "user"
+ jchrisUserDoc = usersDb.open(jchrisUserDoc._id);
+ jchrisUserDoc.type = "not user";
+ try {
+ usersDb.save(jchrisUserDoc);
+ T(false && "should only allow us to save doc when type == 'user'");
+ } catch(e) {
+ T(e.reason == "doc.type must be user");
+ }
+ jchrisUserDoc.type = "user";
+
+ // "roles" must be an array
+ jchrisUserDoc.roles = "not an array";
+ try {
+ usersDb.save(jchrisUserDoc);
+ T(false && "should only allow us to save doc when roles is an array");
+ } catch(e) {
+ T(e.reason == "doc.roles must be an array");
+ }
+ jchrisUserDoc.roles = [];
};
usersDb.deleteDb();
@@ -100,4 +121,4 @@ couchTests.users_db = function(debug) {
);
usersDb.deleteDb(); // cleanup
-} \ No newline at end of file
+}
diff --git a/rel/overlay/share/www/script/test/view_errors.js b/rel/overlay/share/www/script/test/view_errors.js
index a211c061..c05000b7 100644
--- a/rel/overlay/share/www/script/test/view_errors.js
+++ b/rel/overlay/share/www/script/test/view_errors.js
@@ -74,9 +74,6 @@ couchTests.view_errors = function(debug) {
T(e.error == "query_parse_error");
}
- // reduce=false on map views doesn't work, so group=true will
- // never throw for temp reduce views.
-
var designDoc = {
_id:"_design/test",
language: "javascript",
@@ -104,6 +101,15 @@ couchTests.view_errors = function(debug) {
db.view("test/no_reduce", {group: true});
T(0 == 1);
} catch(e) {
+ T(db.last_req.status == 400);
+ T(e.error == "query_parse_error");
+ }
+
+ try {
+ db.view("test/no_reduce", {group_level: 1});
+ T(0 == 1);
+ } catch(e) {
+ T(db.last_req.status == 400);
T(e.error == "query_parse_error");
}
@@ -115,10 +121,23 @@ couchTests.view_errors = function(debug) {
T(e.error == "query_parse_error");
}
+ db.view("test/no_reduce", {reduce: false});
+ TEquals(200, db.last_req.status, "reduce=false for map views (without"
+ + " group or group_level) is allowed");
+
try {
db.view("test/with_reduce", {group: true, reduce: false});
T(0 == 1);
} catch(e) {
+ T(db.last_req.status == 400);
+ T(e.error == "query_parse_error");
+ }
+
+ try {
+ db.view("test/with_reduce", {group_level: 1, reduce: false});
+ T(0 == 1);
+ } catch(e) {
+ T(db.last_req.status == 400);
T(e.error == "query_parse_error");
}
diff --git a/rel/overlay/share/www/script/test/view_multi_key_design.js b/rel/overlay/share/www/script/test/view_multi_key_design.js
index 5a2f645d..c39e73d9 100644
--- a/rel/overlay/share/www/script/test/view_multi_key_design.js
+++ b/rel/overlay/share/www/script/test/view_multi_key_design.js
@@ -34,11 +34,11 @@ couchTests.view_multi_key_design = function(debug) {
reduce:"function (keys, values) { return sum(values); };"
}
}
- }
+ };
T(db.save(designDoc).ok);
// Test that missing keys work too
- var keys = [101,30,15,37,50]
+ var keys = [101,30,15,37,50];
var reduce = db.view("test/summate",{group:true},keys).rows;
T(reduce.length == keys.length-1); // 101 is missing
for(var i=0; i<reduce.length; i++) {
@@ -81,7 +81,7 @@ couchTests.view_multi_key_design = function(debug) {
}
// Test that a map & reduce containing func support keys when reduce=false
- resp = db.view("test/summate", {reduce: false}, keys);
+ var resp = db.view("test/summate", {reduce: false}, keys);
T(resp.rows.length == 5);
// Check that limiting by startkey_docid and endkey_docid get applied
diff --git a/rel/overlay/share/www/script/test/view_sandboxing.js b/rel/overlay/share/www/script/test/view_sandboxing.js
index 9f893b28..02951d9f 100644
--- a/rel/overlay/share/www/script/test/view_sandboxing.js
+++ b/rel/overlay/share/www/script/test/view_sandboxing.js
@@ -42,11 +42,99 @@ couchTests.view_sandboxing = function(debug) {
// make sure that a view cannot access the map_funs array defined used by
// the view server
- var results = db.query(function(doc) { map_funs.push(1); emit(null, doc) });
+ var results = db.query(function(doc) { map_funs.push(1); emit(null, doc); });
T(results.total_rows == 0);
// make sure that a view cannot access the map_results array defined used by
// the view server
- var results = db.query(function(doc) { map_results.push(1); emit(null, doc) });
+ var results = db.query(function(doc) { map_results.push(1); emit(null, doc); });
T(results.total_rows == 0);
+
+ // test for COUCHDB-925
+ // altering 'doc' variable in map function affects other map functions
+ var ddoc = {
+ _id: "_design/foobar",
+ language: "javascript",
+ views: {
+ view1: {
+ map:
+ (function(doc) {
+ if (doc.values) {
+ doc.values = [666];
+ }
+ if (doc.tags) {
+ doc.tags.push("qwerty");
+ }
+ if (doc.tokens) {
+ doc.tokens["c"] = 3;
+ }
+ }).toString()
+ },
+ view2: {
+ map:
+ (function(doc) {
+ if (doc.values) {
+ emit(doc._id, doc.values);
+ }
+ if (doc.tags) {
+ emit(doc._id, doc.tags);
+ }
+ if (doc.tokens) {
+ emit(doc._id, doc.tokens);
+ }
+ }).toString()
+ }
+ }
+ };
+ var doc1 = {
+ _id: "doc1",
+ values: [1, 2, 3]
+ };
+ var doc2 = {
+ _id: "doc2",
+ tags: ["foo", "bar"],
+ tokens: {a: 1, b: 2}
+ };
+
+ db.deleteDb();
+ db.createDb();
+ T(db.save(ddoc).ok);
+ T(db.save(doc1).ok);
+ T(db.save(doc2).ok);
+
+ var view1Results = db.view(
+ "foobar/view1", {bypass_cache: Math.round(Math.random() * 1000)});
+ var view2Results = db.view(
+ "foobar/view2", {bypass_cache: Math.round(Math.random() * 1000)});
+
+ TEquals(0, view1Results.rows.length, "view1 has 0 rows");
+ TEquals(3, view2Results.rows.length, "view2 has 3 rows");
+
+ TEquals(doc1._id, view2Results.rows[0].key);
+ TEquals(doc2._id, view2Results.rows[1].key);
+ TEquals(doc2._id, view2Results.rows[2].key);
+
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=449657
+ TEquals(3, view2Results.rows[0].value.length,
+ "Warning: installed SpiderMonkey version doesn't allow sealing of arrays");
+ if (view2Results.rows[0].value.length === 3) {
+ TEquals(1, view2Results.rows[0].value[0]);
+ TEquals(2, view2Results.rows[0].value[1]);
+ TEquals(3, view2Results.rows[0].value[2]);
+ }
+
+ TEquals(1, view2Results.rows[1].value["a"]);
+ TEquals(2, view2Results.rows[1].value["b"]);
+ TEquals('undefined', typeof view2Results.rows[1].value["c"],
+ "doc2.tokens object was not sealed");
+
+ TEquals(2, view2Results.rows[2].value.length,
+ "Warning: installed SpiderMonkey version doesn't allow sealing of arrays");
+ if (view2Results.rows[2].value.length === 2) {
+ TEquals("foo", view2Results.rows[2].value[0]);
+ TEquals("bar", view2Results.rows[2].value[1]);
+ }
+
+ // cleanup
+ db.deleteDb();
};
diff --git a/rel/overlay/share/www/script/test/view_update_seq.js b/rel/overlay/share/www/script/test/view_update_seq.js
index e6be3f70..9757caa1 100644
--- a/rel/overlay/share/www/script/test/view_update_seq.js
+++ b/rel/overlay/share/www/script/test/view_update_seq.js
@@ -18,7 +18,7 @@ couchTests.view_update_seq = function(debug) {
T(db.info().update_seq == 0);
- resp = db.allDocs({update_seq:true});
+ var resp = db.allDocs({update_seq:true});
T(resp.rows.length == 0);
T(resp.update_seq == 0);
@@ -35,7 +35,7 @@ couchTests.view_update_seq = function(debug) {
reduce:"function (keys, values) { return sum(values); };"
}
}
- }
+ };
T(db.save(designDoc).ok);
T(db.info().update_seq == 1);
diff --git a/rel/overlay/share/www/session.html b/rel/overlay/share/www/session.html
index 581640b0..0ebd943d 100644
--- a/rel/overlay/share/www/session.html
+++ b/rel/overlay/share/www/session.html
@@ -36,7 +36,7 @@ specific language governing permissions and limitations under the License.
}
m = qp.match(/reason=(.*)/);
if (m) {
- reason = decodeURIComponent(m[1]);
+ reason = $.futon.escape(decodeURIComponent(m[1]));
}
});
if (reason) {