couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jch...@apache.org
Subject svn commit: r750305 [4/4] - in /couchdb/branches/rep_security/share/www/script: ./ test/
Date Thu, 05 Mar 2009 03:24:45 GMT
Added: couchdb/branches/rep_security/share/www/script/test/security_validation.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/security_validation.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/security_validation.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/security_validation.js Thu Mar  5
03:24:42 2009
@@ -0,0 +1,246 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.security_validation = function(debug) {
+    // This tests couchdb's security and validation features. This does
+    // not test authentication, except to use test authentication code made
+    // specifically for this testing. It is a WWWW-Authenticate scheme named
+    // X-Couch-Test-Auth, and the user names and passwords are hard coded
+    // on the server-side.
+    // 
+    // We could have used Basic authentication, however the XMLHttpRequest
+    // implementation for Firefox and Safari, and probably other browsers are
+    // broken (Firefox always prompts the user on 401 failures, Safari gives
+    // odd security errors when using different name/passwords, perhaps due
+    // to cross site scripting prevention).  These problems essentially make Basic
+    // authentication testing in the browser impossible. But while hard to
+    // test automated in the browser, Basic auth may still useful for real
+    // world use where these bugs/behaviors don't matter.
+    //
+    // So for testing purposes we are using this custom X-Couch-Test-Auth.
+    // It's identical to Basic auth, except it doesn't even base64 encode
+    // the "username:password" string, it's sent completely plain text.
+    // Firefox and Safari both deal with this correctly (which is to say
+    // they correctly do nothing special).
+  
+  
+    var db = new CouchDB("test_suite_db");
+    db.deleteDb();
+    db.createDb();
+    if (debug) debugger;
+  
+    run_on_modified_server(
+    [{section: "httpd",
+      key: "authentication_handler",
+      value: "{couch_httpd, special_test_authentication_handler}"},
+     {section:"httpd",
+      key: "WWW-Authenticate",
+      value:  "X-Couch-Test-Auth"}],
+    
+    function () {
+    // try saving document usin the wrong credentials
+    var wrongPasswordDb = new CouchDB("test_suite_db",
+      {"WWW-Authenticate": "X-Couch-Test-Auth Damien Katz:foo"}
+    );
+
+    try {
+      wrongPasswordDb.save({foo:1,author:"Damien Katz"});
+      T(false && "Can't get here. Should have thrown an error 1");
+    } catch (e) {
+      T(e.error == "unauthorized");
+      T(wrongPasswordDb.last_req.status == 401);
+    }
+  
+  
+    // Create the design doc that will run custom validation code
+    var designDoc = {
+      _id:"_design/test",
+      language: "javascript",
+      validate_doc_update: "(" + (function (newDoc, oldDoc, userCtx) {
+        // docs should have an author field.
+        if (!newDoc._deleted && !newDoc.author) {
+          throw {forbidden:
+              "Documents must have an author field"};
+        }
+        if (oldDoc && oldDoc.author != userCtx.name) {
+            throw {unauthorized:
+                "You are not the author of this document. You jerk."};
+        }
+      }).toString() + ")"
+    }
+
+    // Save a document normally
+    var userDb = new CouchDB("test_suite_db",
+      {"WWW-Authenticate": "X-Couch-Test-Auth Damien Katz:pecan pie"}
+    );
+  
+    T(userDb.save({_id:"testdoc", foo:1, author:"Damien Katz"}).ok);
+  
+    // Attempt to save the design as a non-admin
+    try {
+      userDb.save(designDoc);
+      T(false && "Can't get here. Should have thrown an error on design doc");
+    } catch (e) {
+      T(e.error == "unauthorized");
+      T(userDb.last_req.status == 401);
+    }
+  
+    // add user as admin
+    db.setAdmins(["Damien Katz"]);
+  
+    T(userDb.save(designDoc).ok);
+
+    // update the document
+    var doc = userDb.open("testdoc");
+    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);
+    }
+
+    // Now attempt to update the document as a different user, Jan 
+    var user2Db = new CouchDB("test_suite_db",
+      {"WWW-Authenticate": "X-Couch-Test-Auth Jan Lehnardt:apple"}
+    );
+
+    var doc = user2Db.open("testdoc");
+    doc.foo=3;
+    try {
+      user2Db.save(doc);
+      T(false && "Can't get here. Should have thrown an error 3");
+    } catch (e) {
+      T(e.error == "unauthorized");
+      T(user2Db.last_req.status == 401);
+    }
+  
+    // Now have Damien change the author to Jan
+    doc = userDb.open("testdoc");
+    doc.author="Jan Lehnardt";
+    T(userDb.save(doc).ok);
+  
+    // Now update the document as Jan
+    doc = user2Db.open("testdoc");
+    doc.foo = 3;
+    T(user2Db.save(doc).ok);
+  
+    // Damien can't delete it
+    try {
+      userDb.deleteDoc(doc);
+      T(false && "Can't get here. Should have thrown an error 4");
+    } catch (e) {
+      T(e.error == "unauthorized");
+      T(userDb.last_req.status == 401);
+    }
+  
+    // Now delete document
+    T(user2Db.deleteDoc(doc).ok);
+  
+  
+    // Now test replication
+    var AuthHeaders = {"WWW-Authenticate": "X-Couch-Test-Auth Christopher Lenz:dog food"};
+    var host = CouchDB.host;
+    var dbPairs = [
+      {source:"test_suite_db_a",
+        target:"test_suite_db_b",
+        options:{}},
+      
+      {source:"test_suite_db_a",
+        target:"http://" + host + "/test_suite_db_b",
+        options: {target_headers: AuthHeaders}},
+          
+      {source:"http://" + host + "/test_suite_db_a",
+        target:"test_suite_db_b",
+        options: {source_headers: AuthHeaders}},
+          
+      {source:"http://" + host + "/test_suite_db_a",
+        target:"http://" + host + "/test_suite_db_b",
+        options:{source_headers: AuthHeaders, target_headers: AuthHeaders}},
+    ]
+    var adminDbA = new CouchDB("test_suite_db_a");
+    var adminDbB = new CouchDB("test_suite_db_b");
+    var dbA = new CouchDB("test_suite_db_a",
+        {"WWW-Authenticate": "X-Couch-Test-Auth Christopher Lenz:dog food"});
+    var dbB = new CouchDB("test_suite_db_b",
+        {"WWW-Authenticate": "X-Couch-Test-Auth Christopher Lenz:dog food"});
+    var xhr;
+    for (var testPair = 0; testPair < dbPairs.length; testPair++) {
+      var A = dbPairs[testPair].source
+      var B = dbPairs[testPair].target
+      var Options = dbPairs[testPair].options
+
+      adminDbA.deleteDb();
+      adminDbA.createDb();
+      adminDbB.deleteDb();
+      adminDbB.createDb();
+    
+      // save and replicate a documents that will and will not pass our design
+      // doc validation function.
+      dbA.save({_id:"foo1",value:"a",author:"Noah Slater"});
+      dbA.save({_id:"foo2",value:"a",author:"Christopher Lenz"});
+      dbA.save({_id:"bad1",value:"a"});
+
+      T(CouchDB.replicate(A, B).ok);
+      T(CouchDB.replicate(B, A).ok);
+
+      T(dbA.open("foo1"));
+      T(dbB.open("foo1"));
+      T(dbA.open("foo2"));
+      T(dbB.open("foo2"));
+    
+      // save the design doc to dbA
+      delete designDoc._rev; // clear rev from previous saves
+      adminDbA.save(designDoc);
+
+      // no affect on already saved docs
+      T(dbA.open("bad1"));
+    
+      // Update some docs on dbB. Since the design hasn't replicated, anything
+      // is allowed.
+    
+      // this edit will fail validation on replication to dbA (no author)
+      T(dbB.save({_id:"bad2",value:"a"}).ok);
+    
+      // this edit will fail security on replication to dbA (wrong author
+      //  replicating the change)
+      var foo1 = dbB.open("foo1");
+      foo1.value = "b";
+      dbB.save(foo1);
+    
+      // this is a legal edit
+      var foo2 = dbB.open("foo2");
+      foo2.value = "b";
+      dbB.save(foo2);
+    
+      var results = CouchDB.replicate(B, A);
+    
+      T(results.ok);
+    
+      T(results.history[0].docs_written == 2);
+      T(results.history[0].doc_write_failures == 1);
+    
+      // bad2 should not be on dbA
+      T(dbA.open("bad2") == null);
+    
+      // The edit to foo1 should not have replicated.
+      T(dbA.open("foo1").value == "a");
+    
+      // The edit to foo2 should have replicated.
+      T(dbA.open("foo2").value == "a");
+    }
+    });
+};
\ No newline at end of file

Propchange: couchdb/branches/rep_security/share/www/script/test/security_validation.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/utf8.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/utf8.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/utf8.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/utf8.js Thu Mar  5 03:24:42 2009
@@ -0,0 +1,41 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.utf8 = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  var texts = [];
+
+  texts[0] = "1. Ascii: hello"
+  texts[1] = "2. Russian: На берегу пустынных
волн"
+  texts[2] = "3. Math: ∮ E⋅da = Q,  n → ∞, ∑ f(i) = ∏ g(i),"
+  texts[3] = "4. Geek: STARGΛ̊TE SG-1"
+  texts[4] = "5. Braille: ⡌⠁⠧⠑ ⠼⠁⠒  ⡍⠜⠇⠑⠹⠰⠎
⡣⠕⠌"
+
+  // check that we can save a reload with full fidelity
+  for (var i=0; i<texts.length; i++) {
+    T(db.save({_id:i.toString(), text:texts[i]}).ok);
+  }
+
+  for (var i=0; i<texts.length; i++) {
+    T(db.open(i.toString()).text == texts[i]);
+  }
+
+  // check that views and key collation don't blow up
+  var rows = db.query(function(doc) { emit(null, doc.text) }).rows;
+  for (var i=0; i<texts.length; i++) {
+    T(rows[i].value == texts[i]);
+  }
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/utf8.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/uuids.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/uuids.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/uuids.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/uuids.js Thu Mar  5 03:24:42 2009
@@ -0,0 +1,47 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.uuids = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+  
+  // a single UUID without an explicit count
+  var xhr = CouchDB.request("POST", "/_uuids");
+  T(xhr.status == 200);
+  var result = JSON.parse(xhr.responseText);
+  T(result.uuids.length == 1);
+  var first = result.uuids[0];
+
+  // a single UUID with an explicit count
+  xhr = CouchDB.request("POST", "/_uuids?count=1");
+  T(xhr.status == 200);
+  result = JSON.parse(xhr.responseText);
+  T(result.uuids.length == 1);
+  var second = result.uuids[0];
+  T(first != second);
+
+  // no collisions with 1,000 UUIDs
+  xhr = CouchDB.request("POST", "/_uuids?count=1000");
+  T(xhr.status == 200);
+  result = JSON.parse(xhr.responseText);
+  T( result.uuids.length == 1000 );
+  var seen = {};
+  for(var i in result.uuids) {
+    var id = result.uuids[i];
+    T(seen[id] === undefined);
+    seen[id] = 1;
+  }
+  
+  // check our library
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/uuids.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_collation.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_collation.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_collation.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_collation.js Thu Mar  5 03:24:42
2009
@@ -0,0 +1,88 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_collation = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  // NOTE, the values are already in their correct sort order. Consider this
+  // a specification of collation of json types.
+
+  var values = [];
+
+  // special values sort before all other types
+  values.push(null);
+  values.push(false);
+  values.push(true);
+
+  // then numbers
+  values.push(1);
+  values.push(2);
+  values.push(3.0);
+  values.push(4);
+
+  // then text, case sensitive
+  values.push("a");
+  values.push("A");
+  values.push("aa");
+  values.push("b");
+  values.push("B");
+  values.push("ba");
+  values.push("bb");
+
+  // then arrays. compared element by element until different.
+  // Longer arrays sort after their prefixes
+  values.push(["a"]);
+  values.push(["b"]);
+  values.push(["b","c"]);
+  values.push(["b","c", "a"]);
+  values.push(["b","d"]);
+  values.push(["b","d", "e"]);
+
+  // then object, compares each key value in the list until different.
+  // larger objects sort after their subset objects.
+  values.push({a:1});
+  values.push({a:2});
+  values.push({b:1});
+  values.push({b:2});
+  values.push({b:2, a:1}); // Member order does matter for collation.
+                           // CouchDB preserves member order
+                           // but doesn't require that clients will.
+                           // (this test might fail if used with a js engine
+                           // that doesn't preserve order)
+  values.push({b:2, c:2});
+
+  for (var i=0; i<values.length; i++) {
+    db.save({_id:(i).toString(), foo:values[i]});
+  }
+
+  var queryFun = function(doc) { emit(doc.foo, null); };
+  var rows = db.query(queryFun).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
+  rows = db.query(queryFun, null, {descending: true}).rows;
+  for (i=0; i<values.length; i++) {
+    T(equals(rows[i].key, values[values.length - 1 -i]));
+  }
+
+  // now check the key query args
+  for (i=1; i<values.length; i++) {
+    var queryOptions = {key:values[i]};
+    rows = db.query(queryFun, null, queryOptions).rows;
+    T(rows.length == 1 && equals(rows[0].key, values[i]));
+  }
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_collation.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_conflicts.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_conflicts.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_conflicts.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_conflicts.js Thu Mar  5 03:24:42
2009
@@ -0,0 +1,49 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_conflicts = function(debug) {
+  var dbA = new CouchDB("test_suite_db_a");
+  dbA.deleteDb();
+  dbA.createDb();
+  var dbB = new CouchDB("test_suite_db_b");
+  dbB.deleteDb();
+  dbB.createDb();
+  if (debug) debugger;
+
+  var docA = {_id: "foo", bar: 42};
+  T(dbA.save(docA).ok);
+  CouchDB.replicate(dbA.name, dbB.name);
+
+  var docB = dbB.open("foo");
+  docB.bar = 43;
+  dbB.save(docB);
+  docA.bar = 41;
+  dbA.save(docA);
+  CouchDB.replicate(dbA.name, dbB.name);
+
+  var doc = dbB.open("foo", {conflicts: true});
+  T(doc._conflicts.length == 1);
+  var conflictRev = doc._conflicts[0];
+  if (doc.bar == 41) { // A won
+    T(conflictRev == docB._rev);
+  } else { // B won
+    T(doc.bar == 43);
+    T(conflictRev == docA._rev);
+  }
+
+  var results = dbB.query(function(doc) {
+    if (doc._conflicts) {
+      emit(doc._id, doc._conflicts);
+    }
+  });
+  T(results.rows[0].value[0] == conflictRev);
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_conflicts.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_errors.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_errors.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_errors.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_errors.js Thu Mar  5 03:24:42
2009
@@ -0,0 +1,43 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_errors = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  var doc = {integer: 1, string: "1", array: [1, 2, 3]};
+  T(db.save(doc).ok);
+
+  // emitting a key value that is undefined should result in that row not
+  // being included in the view results
+  var results = db.query(function(doc) {
+    emit(doc.undef, null);
+  });
+  T(results.total_rows == 0);
+
+  // if a view function throws an exception, its results are not included in
+  // the view index, but the view does not itself raise an error
+  var results = db.query(function(doc) {
+    doc.undef(); // throws an error
+  });
+  T(results.total_rows == 0);
+
+  // if a view function includes an undefined value in the emitted key or
+  // value, an error is logged and the result is not included in the view
+  // index, and the view itself does not raise an error
+  var results = db.query(function(doc) {
+    emit([doc._id, doc.undef], null);
+  });
+  T(results.total_rows == 0);
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_errors.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_include_docs.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_include_docs.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_include_docs.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_include_docs.js Thu Mar  5 03:24:42
2009
@@ -0,0 +1,111 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_include_docs = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  var docs = makeDocs(0, 100);
+  db.bulkSave(docs);
+
+  var designDoc = {
+    _id:"_design/test",
+    language: "javascript",
+    views: {
+      all_docs: {
+        map: "function(doc) { emit(doc.integer, doc.string) }"
+      },
+      with_prev: {
+        map: "function(doc){if(doc.prev) emit(doc._id,{'_rev':doc.prev}); else emit(doc._id,{'_rev':doc._rev});}"
+      },
+      summate: {
+        map:"function (doc) {emit(doc.integer, doc.integer)};",
+        reduce:"function (keys, values) { return sum(values); };"
+      }
+    }
+  }
+  T(db.save(designDoc).ok);
+
+  var resp = db.view('test/all_docs', {include_docs: true, limit: 2});
+  T(resp.rows.length == 2);
+  T(resp.rows[0].id == "0");
+  T(resp.rows[0].doc._id == "0");
+  T(resp.rows[1].id == "1");
+  T(resp.rows[1].doc._id == "1");
+
+  resp = db.view('test/all_docs', {include_docs: true}, [29, 74]);
+  T(resp.rows.length == 2);
+  T(resp.rows[0].doc._id == "29");
+  T(resp.rows[1].doc.integer == 74);
+
+  resp = db.allDocs({limit: 2, skip: 1, include_docs: true});
+  T(resp.rows.length == 2);
+  T(resp.rows[0].doc.integer == 1);
+  T(resp.rows[1].doc.integer == 10);
+
+  resp = db.allDocs({include_docs: true}, ['not_a_doc']);
+  T(resp.rows.length == 1);
+  T(!resp.rows[0].doc);
+
+  resp = db.allDocs({include_docs: true}, ["1", "foo"]);
+  T(resp.rows.length == 2);
+  T(resp.rows[0].doc.integer == 1);
+  T(!resp.rows[1].doc);
+
+  resp = db.allDocs({include_docs: true, limit: 0});
+  T(resp.rows.length == 0);
+
+  // No reduce support
+  try {
+      resp = db.view('test/summate', {include_docs: true});
+      alert(JSON.stringify(resp));
+      T(0==1);
+  } catch (e) {
+      T(e.error == 'query_parse_error');
+  }
+
+  // Reduce support when reduce=false
+  resp = db.view('test/summate', {reduce: false, include_docs: true});
+  T(resp.rows.length == 100);
+
+  // Check emitted _rev controls things
+  resp = db.allDocs({include_docs: true}, ["0"]);
+  var before = resp.rows[0].doc;
+  var after = db.open("0");
+  after.integer = 100
+  after.prev = after._rev;
+  db.save(after);
+  after = db.open("0");
+  T(after._rev != after.prev);
+  T(after.integer == 100);
+
+  // should emit the previous revision
+  resp = db.view("test/with_prev", {include_docs: true}, ["0"]);
+  T(resp.rows[0].doc._id == "0");
+  T(resp.rows[0].doc._rev == before._rev);
+  T(!resp.rows[0].doc.prev);
+  T(resp.rows[0].doc.integer == 0);
+
+  var xhr = CouchDB.request("POST", "/test_suite_db/_compact");
+  T(xhr.status == 202)
+  while (db.info().compact_running) {}
+
+  resp = db.view("test/with_prev", {include_docs: true}, ["0", "23"]);
+  T(resp.rows.length == 2);
+  T(resp.rows[0].key == "0");
+  T(resp.rows[0].id == "0");
+  T(!resp.rows[0].doc);
+  T(resp.rows[0].error == "missing");
+  T(resp.rows[1].doc.integer == 23);
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_include_docs.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_multi_key_all_docs.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_multi_key_all_docs.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_multi_key_all_docs.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_multi_key_all_docs.js Thu Mar
 5 03:24:42 2009
@@ -0,0 +1,54 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_multi_key_all_docs = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  var docs = makeDocs(0, 100);
+  db.bulkSave(docs);
+
+  var keys = ["10","15","30","37","50"];
+  var rows = db.allDocs({},keys).rows;
+  T(rows.length == keys.length);
+  for(var i=0; i<rows.length; i++)
+    T(rows[i].id == keys[i]);
+
+  rows = db.allDocs({limit: 1}, keys).rows;
+  T(rows.length == 1);
+  T(rows[0].id == keys[0]);
+
+  rows = db.allDocs({skip: 2}, keys).rows;
+  T(rows.length == 3);
+  for(var i=0; i<rows.length; i++)
+      T(rows[i].id == keys[i+2]);
+
+  rows = db.allDocs({descending: "true"}, keys).rows;
+  T(rows.length == keys.length);
+  for(var i=0; i<rows.length; i++)
+      T(rows[i].id == keys[keys.length-i-1]);
+
+  rows = db.allDocs({descending: "true", skip: 3, limit:1}, keys).rows;
+  T(rows.length == 1);
+  T(rows[0].id == keys[1]);
+
+  // Check we get invalid rows when the key doesn't exist
+  rows = db.allDocs({}, [1, "i_dont_exist", "0"]).rows;
+  T(rows.length == 3);
+  T(rows[0].error == "not_found");
+  T(!rows[0].id);
+  T(rows[1].error == "not_found");
+  T(!rows[1].id);
+  T(rows[2].id == rows[2].key && rows[2].key == "0");
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_multi_key_all_docs.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_multi_key_design.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_multi_key_design.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_multi_key_design.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_multi_key_design.js Thu Mar 
5 03:24:42 2009
@@ -0,0 +1,138 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_multi_key_design = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  var docs = makeDocs(0, 100);
+  db.bulkSave(docs);
+
+  var designDoc = {
+    _id:"_design/test",
+    language: "javascript",
+    views: {
+      all_docs: {
+        map: "function(doc) { emit(doc.integer, doc.string) }"
+      },
+      multi_emit: {
+        map: "function(doc) {for(var i = 0 ; i < 3 ; i++) { emit(i, doc.integer) ; } }"
+      },
+      summate: {
+        map:"function (doc) {emit(doc.integer, doc.integer)};",
+        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 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++) {
+    T(keys.indexOf(reduce[i].key) != -1);
+    T(reduce[i].key == reduce[i].value);
+  }
+
+  // First, the goods:
+  var keys = [10,15,30,37,50];
+  var rows = db.view("test/all_docs",{},keys).rows;
+  for(var i=0; i<rows.length; i++) {
+    T(keys.indexOf(rows[i].key) != -1);
+    T(rows[i].key == rows[i].value);
+  }
+  
+  var reduce = db.view("test/summate",{group:true},keys).rows;
+  T(reduce.length == keys.length);
+  for(var i=0; i<reduce.length; i++) {
+    T(keys.indexOf(reduce[i].key) != -1);
+    T(reduce[i].key == reduce[i].value);
+  }
+
+  // Test that invalid parameter combinations get rejected
+  var badargs = [{startkey:0}, {endkey:0}, {key: 0}, {group_level: 2}];
+  for(var i in badargs)
+  {
+      try {
+          db.view("test/all_docs",badargs[i],keys);
+          T(0==1);
+      } catch (e) {
+          T(e.error == "query_parse_error");
+      }
+  }
+
+  try {
+      db.view("test/summate",{},keys);
+      T(0==1);
+  } catch (e) {
+      T(e.error == "query_parse_error");
+  }
+
+  // Test that a map & reduce containing func support keys when reduce=false
+  resp = db.view("test/summate", {reduce: false}, keys);
+  T(resp.rows.length == 5);
+
+  // Check that limiting by startkey_docid and endkey_docid get applied
+  // as expected.
+  var curr = db.view("test/multi_emit", {startkey_docid: 21, endkey_docid: 23}, [0, 2]).rows;
+  var exp_key = [ 0,  0,  0,  2,  2,  2] ;
+  var exp_val = [21, 22, 23, 21, 22, 23] ;
+  T(curr.length == 6);
+  for( var i = 0 ; i < 6 ; i++)
+  {
+      T(curr[i].key == exp_key[i]);
+      T(curr[i].value == exp_val[i]);
+  }
+
+  // Check limit works
+  curr = db.view("test/all_docs", {limit: 1}, keys).rows;
+  T(curr.length == 1);
+  T(curr[0].key == 10);
+
+  // Check offset works
+  curr = db.view("test/multi_emit", {skip: 1}, [0]).rows;
+  T(curr.length == 99);
+  T(curr[0].value == 1);
+
+  // Check that dir works
+  curr = db.view("test/multi_emit", {descending: "true"}, [1]).rows;
+  T(curr.length == 100);
+  T(curr[0].value == 99);
+  T(curr[99].value == 0);
+
+  // Check a couple combinations
+  curr = db.view("test/multi_emit", {descending: "true", skip: 3, limit: 2}, [2]).rows;
+  T(curr.length, 2);
+  T(curr[0].value == 96);
+  T(curr[1].value == 95);
+
+  curr = db.view("test/multi_emit", {skip: 2, limit: 3, startkey_docid: "13"}, [0]).rows;
+  T(curr.length == 3);
+  T(curr[0].value == 15);
+  T(curr[1].value == 16);
+  T(curr[2].value == 17);
+
+  curr = db.view("test/multi_emit",
+          {skip: 1, limit: 5, startkey_docid: "25", endkey_docid: "27"}, [1]).rows;
+  T(curr.length == 2);
+  T(curr[0].value == 26);
+  T(curr[1].value == 27);
+
+  curr = db.view("test/multi_emit",
+          {skip: 1, limit: 5, startkey_docid: "28", endkey_docid: "26", descending: "true"},
[1]).rows;
+  T(curr.length == 2);
+  T(curr[0].value == 27);
+  T(curr[1].value == 26);
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_multi_key_design.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_multi_key_temp.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_multi_key_temp.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_multi_key_temp.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_multi_key_temp.js Thu Mar  5
03:24:42 2009
@@ -0,0 +1,37 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_multi_key_temp = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  var docs = makeDocs(0, 100);
+  db.bulkSave(docs);
+
+  var queryFun = function(doc) { emit(doc.integer, doc.integer) };
+  var reduceFun = function (keys, values) { return sum(values); };
+
+  var keys = [10,15,30,37,50];
+  var rows = db.query(queryFun, null, {}, keys).rows;
+  for(var i=0; i<rows.length; i++) {
+    T(keys.indexOf(rows[i].key) != -1);
+    T(rows[i].key == rows[i].value);
+  }
+  
+  var reduce = db.query(queryFun, reduceFun, {group:true}, keys).rows;
+  for(var i=0; i<reduce.length; i++) {
+    T(keys.indexOf(reduce[i].key) != -1);
+    T(reduce[i].key == reduce[i].value);
+  }
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_multi_key_temp.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_pagination.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_pagination.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_pagination.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_pagination.js Thu Mar  5 03:24:42
2009
@@ -0,0 +1,122 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_pagination = function(debug) {
+    var db = new CouchDB("test_suite_db");
+    db.deleteDb();
+    db.createDb();
+    if (debug) debugger;
+
+    var docs = makeDocs(0, 100);
+    db.bulkSave(docs);
+
+    var queryFun = function(doc) { emit(doc.integer, null) };
+    var i;
+
+    // page through the view ascending
+    for (i = 0; i < docs.length; i += 10) {
+      var queryResults = db.query(queryFun, null, {
+        startkey: i,
+        startkey_docid: i,
+        limit: 10
+      });
+      T(queryResults.rows.length == 10)
+      T(queryResults.total_rows == docs.length)
+      T(queryResults.offset == i)
+      var j;
+      for (j = 0; j < 10;j++) {
+        T(queryResults.rows[j].key == i + j);
+      }
+    }
+
+    // page through the view descending
+    for (i = docs.length - 1; i >= 0; i -= 10) {
+      var queryResults = db.query(queryFun, null, {
+        startkey: i,
+        startkey_docid: i,
+        descending: true,
+        limit: 10
+      });
+      T(queryResults.rows.length == 10)
+      T(queryResults.total_rows == docs.length)
+      T(queryResults.offset == docs.length - i - 1)
+      var j;
+      for (j = 0; j < 10; j++) {
+        T(queryResults.rows[j].key == i - j);
+      }
+    }
+
+    // ignore decending=false. CouchDB should just ignore that.
+    for (i = 0; i < docs.length; i += 10) {
+      var queryResults = db.query(queryFun, null, {
+        startkey: i,
+        startkey_docid: i,
+        descending: false,
+        limit: 10
+      });
+      T(queryResults.rows.length == 10)
+      T(queryResults.total_rows == docs.length)
+      T(queryResults.offset == i)
+      var j;
+      for (j = 0; j < 10;j++) {
+        T(queryResults.rows[j].key == i + j);
+      }
+    }
+    
+    // test endkey_docid
+    var queryResults = db.query(function(doc) { emit(null, null);}, null, {
+      startkey: null,
+      startkey_docid: 1,
+      endkey: null,
+      endkey_docid: 40
+    });
+    
+    T(queryResults.rows.length == 35)
+    T(queryResults.total_rows == docs.length)
+    T(queryResults.offset == 1)
+    T(queryResults.rows[0].id == "1");
+    T(queryResults.rows[1].id == "10");
+    T(queryResults.rows[2].id == "11");
+    T(queryResults.rows[3].id == "12");
+    T(queryResults.rows[4].id == "13");
+    T(queryResults.rows[5].id == "14");
+    T(queryResults.rows[6].id == "15");
+    T(queryResults.rows[7].id == "16");
+    T(queryResults.rows[8].id == "17");
+    T(queryResults.rows[9].id == "18");
+    T(queryResults.rows[10].id == "19");
+    T(queryResults.rows[11].id == "2");
+    T(queryResults.rows[12].id == "20");
+    T(queryResults.rows[13].id == "21");
+    T(queryResults.rows[14].id == "22");
+    T(queryResults.rows[15].id == "23");
+    T(queryResults.rows[16].id == "24");
+    T(queryResults.rows[17].id == "25");
+    T(queryResults.rows[18].id == "26");
+    T(queryResults.rows[19].id == "27");
+    T(queryResults.rows[20].id == "28");
+    T(queryResults.rows[21].id == "29");
+    T(queryResults.rows[22].id == "3");
+    T(queryResults.rows[23].id == "30");
+    T(queryResults.rows[24].id == "31");
+    T(queryResults.rows[25].id == "32");
+    T(queryResults.rows[26].id == "33");
+    T(queryResults.rows[27].id == "34");
+    T(queryResults.rows[28].id == "35");
+    T(queryResults.rows[29].id == "36");
+    T(queryResults.rows[30].id == "37");
+    T(queryResults.rows[31].id == "38");
+    T(queryResults.rows[32].id == "39");
+    T(queryResults.rows[33].id == "4");
+    T(queryResults.rows[34].id == "40");
+
+  };

Propchange: couchdb/branches/rep_security/share/www/script/test/view_pagination.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_sandboxing.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_sandboxing.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_sandboxing.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_sandboxing.js Thu Mar  5 03:24:42
2009
@@ -0,0 +1,52 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_sandboxing = function(debug) {
+    var db = new CouchDB("test_suite_db");
+    db.deleteDb();
+    db.createDb();
+    if (debug) debugger;
+
+    var doc = {integer: 1, string: "1", array: [1, 2, 3]};
+    T(db.save(doc).ok);
+/*
+    // make sure that attempting to change the document throws an error
+    var results = db.query(function(doc) {
+      doc.integer = 2;
+      emit(null, doc);
+    });
+    T(results.total_rows == 0);
+
+    var results = db.query(function(doc) {
+      doc.array[0] = 0;
+      emit(null, doc);
+    });
+    T(results.total_rows == 0);
+*/
+    // make sure that a view cannot invoke interpreter internals such as the
+    // garbage collector
+    var results = db.query(function(doc) {
+      gc();
+      emit(null, doc);
+    });
+    T(results.total_rows == 0);
+
+    // 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) });
+    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) });
+    T(results.total_rows == 0);
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_sandboxing.js
------------------------------------------------------------------------------
    svn:eol-style = native

Added: couchdb/branches/rep_security/share/www/script/test/view_xml.js
URL: http://svn.apache.org/viewvc/couchdb/branches/rep_security/share/www/script/test/view_xml.js?rev=750305&view=auto
==============================================================================
--- couchdb/branches/rep_security/share/www/script/test/view_xml.js (added)
+++ couchdb/branches/rep_security/share/www/script/test/view_xml.js Thu Mar  5 03:24:42 2009
@@ -0,0 +1,39 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License.  You may obtain a copy
+// of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+couchTests.view_xml = function(debug) {
+  var db = new CouchDB("test_suite_db");
+  db.deleteDb();
+  db.createDb();
+  if (debug) debugger;
+
+  db.save({content: "<doc><title id='xml'>Testing XML</title></doc>"});
+  db.save({content: "<doc><title id='e4x'>Testing E4X</title></doc>"});
+
+  var results = db.query(
+    "function(doc) {\n" +
+    "  var xml = new XML(doc.content);\n" +
+    "  emit(xml.title.text(), null);\n" +
+    "}");
+  T(results.total_rows == 2);
+  T(results.rows[0].key == "Testing E4X");
+  T(results.rows[1].key == "Testing XML");
+
+  var results = db.query(
+    "function(doc) {\n" +
+    "  var xml = new XML(doc.content);\n" +
+    "  emit(xml.title.@id, null);\n" +
+    "}");
+  T(results.total_rows == 2);
+  T(results.rows[0].key == "e4x");
+  T(results.rows[1].key == "xml");
+};

Propchange: couchdb/branches/rep_security/share/www/script/test/view_xml.js
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message