diff options
Diffstat (limited to 'rel/overlay/share/www/script/test')
30 files changed, 503 insertions, 130 deletions
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);  | 
