From b518f01a4def8eac085c76599ecf1b03aeff06f8 Mon Sep 17 00:00:00 2001 From: Juanjo Rodriguez Date: Mon, 13 Jul 2020 22:44:05 +0200 Subject: port update_documents.js into elixir --- test/elixir/README.md | 2 +- test/elixir/test/update_documents_test.exs | 324 +++++++++++++++++++++++++++++ test/javascript/tests/update_documents.js | 2 +- 3 files changed, 326 insertions(+), 2 deletions(-) create mode 100644 test/elixir/test/update_documents_test.exs diff --git a/test/elixir/README.md b/test/elixir/README.md index 7f11d87cf..566364a34 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. + "

New World

"]; + }; + // + return [null, "

Empty World

"]; + }; + // 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, "

hello doc

"]; + } + """, + "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 = "

bumped it!

"; + 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 = "

bumped it!

"; + 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 == "

hello doc

" + 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 == "

Empty World

" + 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 == "

New World

" + + 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 == "

bumped it!

" + + 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 == "

bumped it!

" + + 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 == "

bumped it!

" + + 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"}); -- cgit v1.2.1