summaryrefslogtreecommitdiff
path: root/rel/overlay/share/www/script
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2011-10-04 13:11:12 -0700
committerAdam Kocoloski <adam@cloudant.com>2011-10-04 13:11:12 -0700
commitda7284ed2844926c7df0efef12ba30d8e2e6d039 (patch)
tree10fa2d5cf35bfae4d48fc632924cec98ee02a22a /rel/overlay/share/www/script
parentb57aadd742e4f8cc925ba4f005ae658c43a7c5b4 (diff)
parent4e19639a64d3033e1cc7c22a0b7404d277643c78 (diff)
Merge pull request #67 from cloudant/12645-merge_latest_1.1.x
Diffstat (limited to 'rel/overlay/share/www/script')
-rw-r--r--rel/overlay/share/www/script/couch_test_runner.js15
-rw-r--r--rel/overlay/share/www/script/futon.browse.js3
-rw-r--r--rel/overlay/share/www/script/test/all_docs.js7
-rw-r--r--rel/overlay/share/www/script/test/basics.js19
-rw-r--r--rel/overlay/share/www/script/test/changes.js26
-rw-r--r--rel/overlay/share/www/script/test/design_docs.js39
-rw-r--r--rel/overlay/share/www/script/test/etags_views.js8
-rw-r--r--rel/overlay/share/www/script/test/jsonp.js2
-rw-r--r--rel/overlay/share/www/script/test/recreate_doc.js65
-rw-r--r--rel/overlay/share/www/script/test/show_documents.js26
-rw-r--r--rel/overlay/share/www/script/test/update_documents.js38
-rw-r--r--rel/overlay/share/www/script/test/view_collation_raw.js9
12 files changed, 253 insertions, 4 deletions
diff --git a/rel/overlay/share/www/script/couch_test_runner.js b/rel/overlay/share/www/script/couch_test_runner.js
index 55a6533f..e14640b6 100644
--- a/rel/overlay/share/www/script/couch_test_runner.js
+++ b/rel/overlay/share/www/script/couch_test_runner.js
@@ -414,9 +414,22 @@ function waitForSuccess(fun, tag) {
function waitForRestart() {
var waiting = true;
- while (waiting) {
+ // Wait for the server to go down but don't
+ // wait too long because we might miss the
+ // unavailable period.
+ var count = 25;
+ while (waiting && count > 0) {
+ count--;
try {
CouchDB.request("GET", "/");
+ } catch(e) {
+ waiting = false;
+ }
+ }
+ // Wait for it to come back up
+ waiting = true;
+ while (waiting) {
+ try {
CouchDB.request("GET", "/");
waiting = false;
} catch(e) {
diff --git a/rel/overlay/share/www/script/futon.browse.js b/rel/overlay/share/www/script/futon.browse.js
index 0228b83e..5c10773a 100644
--- a/rel/overlay/share/www/script/futon.browse.js
+++ b/rel/overlay/share/www/script/futon.browse.js
@@ -1275,8 +1275,7 @@
return false;
}).prependTo($("a", li));
}
- },
-
+ }
});
function encodeAttachment(name) {
diff --git a/rel/overlay/share/www/script/test/all_docs.js b/rel/overlay/share/www/script/test/all_docs.js
index 1d83aa95..1afe701d 100644
--- a/rel/overlay/share/www/script/test/all_docs.js
+++ b/rel/overlay/share/www/script/test/all_docs.js
@@ -41,6 +41,13 @@ couchTests.all_docs = function(debug) {
var all = db.allDocs({startkey:"2"});
T(all.offset == 2);
+ // Confirm that queries may assume raw collation.
+ var raw = db.allDocs({
+ startkey: "org.couchdb.user:",
+ endkey: "org.couchdb.user;"
+ });
+ TEquals(0, raw.rows.length);
+
// check that the docs show up in the seq view in the order they were created
var changes = db.changes();
var ids = ["0","3","1","2"];
diff --git a/rel/overlay/share/www/script/test/basics.js b/rel/overlay/share/www/script/test/basics.js
index 30c27c11..5dcf9fa9 100644
--- a/rel/overlay/share/www/script/test/basics.js
+++ b/rel/overlay/share/www/script/test/basics.js
@@ -246,4 +246,23 @@ couchTests.basics = function(debug) {
result = JSON.parse(xhr.responseText);
TEquals("bad_request", result.error);
TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason);
+
+ // On restart, a request for creating a database that already exists can
+ // not override the existing database file
+ db = new CouchDB("test_suite_foobar");
+ db.deleteDb();
+ xhr = CouchDB.request("PUT", "/" + db.name);
+ TEquals(201, xhr.status);
+
+ TEquals(true, db.save({"_id": "doc1"}).ok);
+ TEquals(true, db.ensureFullCommit().ok);
+
+ TEquals(1, db.info().doc_count);
+
+ restartServer();
+
+ xhr = CouchDB.request("PUT", "/" + db.name);
+ TEquals(412, xhr.status);
+
+ TEquals(1, db.info().doc_count);
};
diff --git a/rel/overlay/share/www/script/test/changes.js b/rel/overlay/share/www/script/test/changes.js
index ea22bfb3..284f1985 100644
--- a/rel/overlay/share/www/script/test/changes.js
+++ b/rel/overlay/share/www/script/test/changes.js
@@ -507,6 +507,32 @@ couchTests.changes = function(debug) {
CouchDB.request("GET", "/" + db.name + "/_changes");
TEquals(0, CouchDB.requestStats('httpd', 'clients_requesting_changes').current);
+ // COUCHDB-1256
+ T(db.deleteDb());
+ T(db.createDb());
+
+ T(db.save({"_id":"foo", "a" : 123}).ok);
+ T(db.save({"_id":"bar", "a" : 456}).ok);
+
+ options = {
+ headers: {"Content-Type": "application/json"},
+ body: JSON.stringify({"_rev":"1-cc609831f0ca66e8cd3d4c1e0d98108a", "a":456})
+ };
+ req = CouchDB.request("PUT", "/" + db.name + "/foo?new_edits=false", options);
+
+ req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs");
+ resp = JSON.parse(req.responseText);
+
+ TEquals(3, resp.last_seq);
+ TEquals(2, resp.results.length);
+
+ req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs&since=2");
+ resp = JSON.parse(req.responseText);
+
+ TEquals(3, resp.last_seq);
+ TEquals(1, resp.results.length);
+ TEquals(2, resp.results[0].changes.length);
+
// cleanup
db.deleteDb();
};
diff --git a/rel/overlay/share/www/script/test/design_docs.js b/rel/overlay/share/www/script/test/design_docs.js
index 702f0441..dd38858a 100644
--- a/rel/overlay/share/www/script/test/design_docs.js
+++ b/rel/overlay/share/www/script/test/design_docs.js
@@ -421,6 +421,45 @@ couchTests.design_docs = function(debug) {
run_on_modified_server(server_config, testFun);
+ // COUCHDB-1227 - if a design document is deleted, by adding a "_deleted"
+ // field with the boolean value true, its validate_doc_update functions
+ // should no longer have effect.
+ db.deleteDb();
+ db.createDb();
+ var ddoc = {
+ _id: "_design/test",
+ language: "javascript",
+ validate_doc_update: (function(newDoc, oldDoc, userCtx, secObj) {
+ if (newDoc.value % 2 == 0) {
+ throw({forbidden: "dont like even numbers"});
+ }
+ return true;
+ }).toString()
+ };
+
+ TEquals(true, db.save(ddoc).ok);
+ try {
+ db.save({_id: "doc1", value: 4});
+ T(false, "doc insertion should have failed");
+ } catch (x) {
+ TEquals("forbidden", x.error);
+ }
+
+ var doc = db.open("doc1");
+ TEquals(null, doc);
+ ddoc._deleted = true;
+ TEquals(true, db.save(ddoc).ok);
+
+ try {
+ TEquals(true, db.save({_id: "doc1", value: 4}).ok);
+ } catch (x) {
+ T(false, "doc insertion should have succeeded");
+ }
+
+ doc = db.open("doc1");
+ TEquals(true, doc !== null, "doc was not persisted");
+ TEquals(4, doc.value);
+
// cleanup
db.deleteDb();
db2.deleteDb();
diff --git a/rel/overlay/share/www/script/test/etags_views.js b/rel/overlay/share/www/script/test/etags_views.js
index 34116f71..f6a4e1a5 100644
--- a/rel/overlay/share/www/script/test/etags_views.js
+++ b/rel/overlay/share/www/script/test/etags_views.js
@@ -70,6 +70,14 @@ couchTests.etags_views = function(debug) {
xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView");
var etag1 = xhr.getResponseHeader("etag");
T(etag1 == etag);
+
+ // verify ETag always changes for include_docs=true on update
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView?include_docs=true");
+ var etag1 = xhr.getResponseHeader("etag");
+ T(db.save({"_id":"doc2", "foo":"bar"}).ok);
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/basicView?include_docs=true");
+ var etag2 = xhr.getResponseHeader("etag");
+ T(etag1 != etag2);
// Verify that purges affect etags
xhr = CouchDB.request("GET", "/test_suite_db/_design/etags/_view/fooView");
diff --git a/rel/overlay/share/www/script/test/jsonp.js b/rel/overlay/share/www/script/test/jsonp.js
index 9aba7189..d1bca94a 100644
--- a/rel/overlay/share/www/script/test/jsonp.js
+++ b/rel/overlay/share/www/script/test/jsonp.js
@@ -48,6 +48,7 @@ couchTests.jsonp = function(debug) {
// Test unchunked callbacks.
var xhr = CouchDB.request("GET", "/test_suite_db/0?callback=jsonp_no_chunk");
+ TEquals("text/javascript", xhr.getResponseHeader("Content-Type"));
T(xhr.status == 200);
jsonp_flag = 0;
eval(xhr.responseText);
@@ -70,6 +71,7 @@ couchTests.jsonp = function(debug) {
var url = "/test_suite_db/_design/test/_view/all_docs?callback=jsonp_chunk";
xhr = CouchDB.request("GET", url);
+ TEquals("text/javascript", xhr.getResponseHeader("Content-Type"));
T(xhr.status == 200);
jsonp_flag = 0;
eval(xhr.responseText);
diff --git a/rel/overlay/share/www/script/test/recreate_doc.js b/rel/overlay/share/www/script/test/recreate_doc.js
index 05843558..f9723793 100644
--- a/rel/overlay/share/www/script/test/recreate_doc.js
+++ b/rel/overlay/share/www/script/test/recreate_doc.js
@@ -77,4 +77,69 @@ couchTests.recreate_doc = function(debug) {
} catch (e) {
T(e.error == "conflict");
}
+
+ db.deleteDb();
+ db.createDb();
+
+ // Helper function to create a doc with multiple revisions
+ // that are compacted away to ?REV_MISSING.
+
+ var createDoc = function(docid) {
+ var ret = [{_id: docid, count: 0}];
+ T(db.save(ret[0]).ok);
+ for(var i = 0; i < 2; i++) {
+ ret[ret.length] = {
+ _id: docid,
+ _rev: ret[ret.length-1]._rev,
+ count: ret[ret.length-1].count+1
+ };
+ T(db.save(ret[ret.length-1]).ok);
+ }
+ db.compact();
+ while(db.info().compact_running) {}
+ return ret;
+ }
+
+ // Helper function to check that there are no duplicates
+ // in the changes feed and that it has proper update
+ // sequence ordering.
+
+ var checkChanges = function() {
+ // Assert that there are no duplicates in _changes.
+ var req = CouchDB.request("GET", "/test_suite_db/_changes");
+ var resp = JSON.parse(req.responseText);
+ var docids = {};
+ var prev_seq = -1;
+ for(var i = 0; i < resp.results.length; i++) {
+ row = resp.results[i];
+ T(row.seq > prev_seq, "Unordered _changes feed.");
+ T(docids[row.id] === undefined, "Duplicates in _changes feed.");
+ prev_seq = row.seq;
+ docids[row.id] = true;
+ }
+ };
+
+ // COUCHDB-1265 - Check that the changes feed remains proper
+ // after we try and break the update_seq tree.
+
+ // This first case is the one originally reported and "fixed"
+ // in COUCHDB-1265. Reinserting an old revision into the
+ // revision tree causes duplicates in the update_seq tree.
+
+ var revs = createDoc("a");
+ T(db.save(revs[1], {new_edits: false}).ok);
+ T(db.save(revs[revs.length-1]).ok);
+ checkChanges();
+
+ // The original fix for COUCHDB-1265 is not entirely correct
+ // as it didn't consider the possibility that a compaction
+ // might run after the original tree screw up.
+
+ revs = createDoc("b");
+ T(db.save(revs[1], {new_edits: false}).ok);
+ db.compact();
+ while(db.info().compact_running) {}
+ T(db.save(revs[revs.length-1]).ok);
+ checkChanges();
+
};
diff --git a/rel/overlay/share/www/script/test/show_documents.js b/rel/overlay/share/www/script/test/show_documents.js
index 55ed9698..cf73ed57 100644
--- a/rel/overlay/share/www/script/test/show_documents.js
+++ b/rel/overlay/share/www/script/test/show_documents.js
@@ -90,6 +90,24 @@ couchTests.show_documents = function(debug) {
start({"X-Couch-Test-Header": "Yeah"});
send("Hey");
}),
+ "list-api-provides" : stringFun(function(doc, req) {
+ provides("text", function(){
+ send("foo, ");
+ send("bar, ");
+ send("baz!");
+ })
+ }),
+ "list-api-provides-and-return" : stringFun(function(doc, req) {
+ provides("text", function(){
+ send("4, ");
+ send("5, ");
+ send("6, ");
+ return "7!";
+ })
+ send("1, ");
+ send("2, ");
+ return "3, ";
+ }),
"list-api-mix" : stringFun(function(doc, req) {
start({"X-Couch-Test-Header": "Yeah"});
send("Hey ");
@@ -395,6 +413,14 @@ couchTests.show_documents = function(debug) {
T(xhr.responseText == "Hey");
TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool");
+ // test list() compatible API with provides function
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides/foo?format=text");
+ TEquals(xhr.responseText, "foo, bar, baz!", "should join chunks to response body");
+
+ // should keep next result order: chunks + return value + provided chunks + provided return value
+ xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-provides-and-return/foo?format=text");
+ TEquals(xhr.responseText, "1, 2, 3, 4, 5, 6, 7!", "should not break 1..7 range");
+
xhr = CouchDB.request("GET", "/test_suite_db/_design/template/_show/list-api-mix/foo");
T(xhr.responseText == "Hey Dude");
TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool");
diff --git a/rel/overlay/share/www/script/test/update_documents.js b/rel/overlay/share/www/script/test/update_documents.js
index 49d3b68a..59af4597 100644
--- a/rel/overlay/share/www/script/test/update_documents.js
+++ b/rel/overlay/share/www/script/test/update_documents.js
@@ -75,6 +75,17 @@ couchTests.update_documents = function(debug) {
}),
"get-uuid" : stringFun(function(doc, req) {
return [null, req.uuid];
+ }),
+ "code-n-bump" : stringFun(function(doc,req) {
+ if (!doc.counter) doc.counter = 0;
+ doc.counter += 1;
+ var message = "<h1>bumped it!</h1>";
+ resp = {"code": 302, "body": message}
+ return [doc, resp];
+ }),
+ "resp-code" : stringFun(function(doc,req) {
+ resp = {"code": 302}
+ return [null, resp];
})
}
};
@@ -165,4 +176,31 @@ couchTests.update_documents = function(debug) {
T(xhr.status == 200);
T(xhr.responseText.length == 32);
+ // COUCHDB-1229 - allow slashes in doc ids for update handlers
+ // /db/_design/doc/_update/handler/doc/id
+
+ var doc = {
+ _id:"with/slash",
+ counter:1
+ };
+ db.save(doc);
+ xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/bump-counter/with/slash");
+ TEquals(201, xhr.status, "should return a 200 status");
+ TEquals("<h1>bumped it!</h1>", xhr.responseText, "should report bumping");
+
+ var doc = db.open("with/slash");
+ TEquals(2, doc.counter, "counter should be 2");
+
+ // COUCHDB-648 - the code in the JSON response should be honored
+
+ xhr = CouchDB.request("PUT", "/test_suite_db/_design/update/_update/code-n-bump/"+docid, {
+ headers : {"X-Couch-Full-Commit":"true"}
+ });
+ T(xhr.status == 302);
+ T(xhr.responseText == "<h1>bumped it!</h1>");
+ doc = db.open(docid);
+ T(doc.counter == 3);
+
+ xhr = CouchDB.request("POST", "/test_suite_db/_design/update/_update/resp-code/");
+ T(xhr.status == 302);
};
diff --git a/rel/overlay/share/www/script/test/view_collation_raw.js b/rel/overlay/share/www/script/test/view_collation_raw.js
index 31624cdb..779f7eb8 100644
--- a/rel/overlay/share/www/script/test/view_collation_raw.js
+++ b/rel/overlay/share/www/script/test/view_collation_raw.js
@@ -76,12 +76,19 @@ couchTests.view_collation_raw = function(debug) {
}
}
T(db.save(designDoc).ok);
+
+ // Confirm that everything collates correctly.
var rows = db.view("test/test").rows;
for (i=0; i<values.length; i++) {
T(equals(rows[i].key, values[i]));
}
- // everything has collated correctly. Now to check the descending output
+ // Confirm that couch allows raw semantics in key ranges.
+ rows = db.view("test/test", {startkey:"Z", endkey:"a"}).rows;
+ TEquals(1, rows.length);
+ TEquals("a", rows[0].key);
+
+ // Check the descending output.
rows = db.view("test/test", {descending: true}).rows;
for (i=0; i<values.length; i++) {
T(equals(rows[i].key, values[values.length - 1 -i]));