summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuanjo Rodriguez <juanjo@apache.org>2020-07-13 22:44:05 +0200
committerJuanjo Rodriguez <jjrodrig@gmail.com>2020-07-24 12:17:40 +0200
commitf4517a6c491439d45d8869bff17f04a6868c1753 (patch)
tree7a281618c0468a004bc8c514109b54b2f8150d70
parentd267dc533a6cdecd06eb124ec30b6596df877d57 (diff)
downloadcouchdb-f4517a6c491439d45d8869bff17f04a6868c1753.tar.gz
port update_documents.js into elixir
-rw-r--r--test/elixir/README.md2
-rw-r--r--test/elixir/test/update_documents_test.exs324
-rw-r--r--test/javascript/tests/update_documents.js2
3 files changed, 326 insertions, 2 deletions
diff --git a/test/elixir/README.md b/test/elixir/README.md
index fa2e2e430..a01ab6b8a 100644
--- a/test/elixir/README.md
+++ b/test/elixir/README.md
@@ -93,7 +93,7 @@ X means done, - means partially
- [X] Port security_validation.js
- [ ] Port show_documents.js
- [ ] Port stats.js
- - [ ] Port update_documents.js
+ - [X] Port update_documents.js
- [X] Port users_db.js
- [ ] Port users_db_security.js
- [X] Port utf8.js
diff --git a/test/elixir/test/update_documents_test.exs b/test/elixir/test/update_documents_test.exs
new file mode 100644
index 000000000..c29b31a4d
--- /dev/null
+++ b/test/elixir/test/update_documents_test.exs
@@ -0,0 +1,324 @@
+defmodule UpdateDocumentsTest do
+ use CouchTestCase
+
+ @ddoc %{
+ _id: "_design/update",
+ language: "javascript",
+ updates: %{
+ hello: """
+ function(doc, req) {
+ if (!doc) {
+ if (req.id) {
+ return [
+ // Creates a new document with the PUT docid,
+ { _id : req.id,
+ reqs : [req] },
+ // and returns an HTML response to the client.
+ "<p>New World</p>"];
+ };
+ //
+ return [null, "<p>Empty World</p>"];
+ };
+ // we can update the document inline
+ doc.world = "hello";
+ // we can record aspects of the request or use them in application logic.
+ doc.reqs && doc.reqs.push(req);
+ doc.edited_by = req.userCtx;
+ return [doc, "<p>hello doc</p>"];
+ }
+ """,
+ "in-place": """
+ function(doc, req) {
+ var field = req.query.field;
+ var value = req.query.value;
+ var message = "set "+field+" to "+value;
+ doc[field] = value;
+ return [doc, message];
+ }
+ """,
+ "form-update": """
+ function(doc, req) {
+ for (var field in req.form) {
+ doc[field] = req.form[field];
+ }
+ var message = "updated doc from form";
+ return [doc, message];
+ }
+ """,
+ "bump-counter": """
+ function(doc, req) {
+ if (!doc.counter) doc.counter = 0;
+ doc.counter += 1;
+ var message = "<h1>bumped it!</h1>";
+ return [doc, message];
+ }
+ """,
+ error: """
+ function(doc, req) {
+ superFail.badCrash;
+ }
+ """,
+ "get-uuid": """
+ function(doc, req) {
+ return [null, req.uuid];
+ }
+ """,
+ "code-n-bump": """
+ function(doc,req) {
+ if (!doc.counter) doc.counter = 0;
+ doc.counter += 1;
+ var message = "<h1>bumped it!</h1>";
+ resp = {"code": 302, "body": message}
+ return [doc, resp];
+ }
+ """,
+ "resp-code": """
+ function(doc,req) {
+ resp = {"code": 302}
+ return [null, resp];
+ }
+ """,
+ "resp-code-and-json": """
+ function(doc,req) {
+ resp = {"code": 302, "json": {"ok": true}}
+ return [{"_id": req["uuid"]}, resp];
+ }
+ """,
+ binary: """
+ function(doc, req) {
+ var resp = {
+ "headers" : {
+ "Content-Type" : "application/octet-stream"
+ },
+ "base64" : "aGVsbG8gd29ybGQh" // "hello world!" encoded
+ };
+ return [doc, resp];
+ }
+ """,
+ empty: """
+ function(doc, req) {
+ return [{}, 'oops'];
+ }
+ """
+ }
+ }
+
+ @document %{word: "plankton", name: "Rusty"}
+
+ @tag :with_db
+ test "update error invalid path", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ resp = Couch.post("/#{db_name}/_design/update/_update/")
+ assert resp.status_code == 404
+ assert resp.body["reason"] == "Invalid path."
+ end
+
+ @tag :with_db
+ test "update document", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+ {:ok, resp} = create_doc(db_name, @document)
+ docid = resp.body["id"]
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/hello/#{docid}")
+ assert resp.status_code == 201
+ assert resp.body == "<p>hello doc</p>"
+ assert String.contains?(resp.headers["Content-Type"], "charset=utf-8")
+ assert resp.headers["X-Couch-Id"] == docid
+
+ resp = Couch.get("/#{db_name}/#{docid}")
+ assert resp.status_code == 200
+ assert resp.body["world"] == "hello"
+
+ # Fix for COUCHDB-379
+ assert String.starts_with?(resp.headers["Server"], "CouchDB")
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/hello")
+ assert resp.status_code == 200
+ assert resp.body == "<p>Empty World</p>"
+ end
+
+ @tag :with_db
+ test "GET is not allowed", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ resp = Couch.get("/#{db_name}/_design/update/_update/hello")
+ assert resp.body["error"] == "method_not_allowed"
+ end
+
+ @tag :with_db
+ test "doc can be created", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ resp = Couch.get("/#{db_name}/nonExistingDoc")
+ assert resp.status_code == 404
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/hello/nonExistingDoc")
+ assert resp.status_code == 201
+ assert resp.body == "<p>New World</p>"
+
+ resp = Couch.get("/#{db_name}/nonExistingDoc")
+ assert resp.status_code == 200
+ end
+
+ @tag :with_db
+ test "in place update", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ {:ok, resp} = create_doc(db_name, @document)
+ docid = resp.body["id"]
+
+ resp =
+ Couch.put(
+ "/#{db_name}/_design/update/_update/in-place/#{docid}?field=title&value=test"
+ )
+
+ assert resp.status_code == 201
+ assert resp.body == "set title to test"
+ resp = Couch.get("/#{db_name}/#{docid}")
+ assert resp.status_code == 200
+ assert resp.body["title"] == "test"
+ end
+
+ @tag :with_db
+ test "form update via application/x-www-form-urlencoded", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ {:ok, resp} = create_doc(db_name, @document)
+ docid = resp.body["id"]
+
+ resp =
+ Couch.put(
+ "/#{db_name}/_design/update/_update/form-update/#{docid}",
+ headers: ["Content-Type": "application/x-www-form-urlencoded"],
+ body: "formfoo=bar&formbar=foo"
+ )
+
+ assert resp.status_code == 201
+ assert resp.body == "updated doc from form"
+
+ resp = Couch.get("/#{db_name}/#{docid}")
+ assert resp.status_code == 200
+ assert resp.body["formfoo"] == "bar"
+ assert resp.body["formbar"] == "foo"
+ end
+
+ @tag :with_db
+ test "bump counter", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ {:ok, resp} = create_doc(db_name, @document)
+ docid = resp.body["id"]
+
+ resp =
+ Couch.put("/#{db_name}/_design/update/_update/bump-counter/#{docid}",
+ headers: ["X-Couch-Full-Commit": "true"]
+ )
+
+ assert resp.status_code == 201
+ assert resp.body == "<h1>bumped it!</h1>"
+
+ resp = Couch.get("/#{db_name}/#{docid}")
+ assert resp.status_code == 200
+ assert resp.body["counter"] == 1
+
+ resp =
+ Couch.put("/#{db_name}/_design/update/_update/bump-counter/#{docid}",
+ headers: ["X-Couch-Full-Commit": "true"]
+ )
+
+ newrev = resp.headers["X-Couch-Update-NewRev"]
+
+ resp = Couch.get("/#{db_name}/#{docid}")
+ assert resp.status_code == 200
+ assert resp.body["counter"] == 2
+ assert resp.body["_rev"] == newrev
+ end
+
+ @tag :with_db
+ test "Server provides UUID when POSTing without an ID in the URL", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+ resp = Couch.put("/#{db_name}/_design/update/_update/get-uuid/")
+ assert resp.status_code == 200
+ assert String.length(resp.body) == 32
+ end
+
+ @tag :with_db
+ test "COUCHDB-1229 - allow slashes in doc ids for update handlers", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ create_doc(db_name, %{_id: "with/slash", counter: 1})
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/bump-counter/with/slash")
+ assert resp.status_code == 201
+ assert resp.body == "<h1>bumped it!</h1>"
+
+ resp = Couch.get("/#{db_name}/with%2Fslash")
+ assert resp.status_code == 200
+ assert resp.body["counter"] == 2
+ end
+
+ @tag :with_db
+ test "COUCHDB-648 - the code in the JSON response should be honored", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ {:ok, resp} = create_doc(db_name, @document)
+ docid = resp.body["id"]
+
+ Couch.put("/#{db_name}/_design/update/_update/bump-counter/#{docid}")
+ Couch.put("/#{db_name}/_design/update/_update/bump-counter/#{docid}")
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/code-n-bump/#{docid}")
+ assert resp.status_code == 302
+ assert resp.body == "<h1>bumped it!</h1>"
+
+ resp = Couch.get("/#{db_name}/#{docid}")
+ assert resp.status_code == 200
+ assert resp.body["counter"] == 3
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/resp-code/")
+ assert resp.status_code == 302
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/resp-code-and-json/")
+ assert resp.status_code == 302
+ assert resp.body["ok"] == true
+ end
+
+ @tag :with_db
+ test "base64 response", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ {:ok, resp} = create_doc(db_name, @document)
+ docid = resp.body["id"]
+
+ resp =
+ Couch.put("/#{db_name}/_design/update/_update/binary/#{docid}",
+ body: "rubbish"
+ )
+
+ assert resp.status_code == 201
+ assert resp.body == "hello world!"
+ assert String.contains?(resp.headers["Content-Type"], "application/octet-stream")
+ end
+
+ @tag :with_db
+ test "Insert doc with empty id", context do
+ db_name = context[:db_name]
+ create_doc(db_name, @ddoc)
+
+ resp = Couch.put("/#{db_name}/_design/update/_update/empty/foo")
+ assert resp.status_code == 400
+ assert resp.body["reason"] == "Document id must not be empty"
+ end
+end
diff --git a/test/javascript/tests/update_documents.js b/test/javascript/tests/update_documents.js
index 6cd4a91d6..913c99a57 100644
--- a/test/javascript/tests/update_documents.js
+++ b/test/javascript/tests/update_documents.js
@@ -10,7 +10,7 @@
// License for the specific language governing permissions and limitations under
// the License.
-
+couchTests.elixir = true
couchTests.update_documents = function(debug) {
var db_name = get_random_db_name();
var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});