This is an automated email from the ASF dual-hosted git repository. jiahuili430 pushed a commit to branch fix-elixir-tests in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit d97618fd7aba5e50c2d0628709fbbcc5b5d2cd11 Author: Jiahui Li <[email protected]> AuthorDate: Wed Dec 10 14:31:57 2025 -0600 Modify suite.elixir --- t.py | 25 + test/elixir/test/config/search.elixir | 3 +- test/elixir/test/config/skip.elixir | 32 +- test/elixir/test/config/suite.elixir | 47 +- test/elixir/test/cookie_auth_test.exs | 41 +- .../{disk_monitor.exs => disk_monitor_test.exs} | 0 test/elixir/test/rewrite_js_test.exs | 361 ++++---- test/elixir/test/rewrite_test.exs | 937 +++++++++++---------- 8 files changed, 719 insertions(+), 727 deletions(-) diff --git a/t.py b/t.py new file mode 100644 index 000000000..5862bd78b --- /dev/null +++ b/t.py @@ -0,0 +1,25 @@ +import glob +import json +import os +import re + +module_pattern = re.compile(r"defmodule\s+([A-Za-z0-9_.]+)\s+do") +test_pattern = re.compile(r'test\s+["](.*)["]') +result = {} + +files = glob.glob(os.path.join("test/elixir/test/**/*_test.exs"), recursive=True) + +for file_path in files: + with open(file_path, "r", encoding="utf-8") as f: + content = f.read() + + module_match = module_pattern.search(content) + if not module_match: + continue + module_name = module_match.group(1) + + tests = [m for m in test_pattern.findall(content)] + tests.sort() + result[module_name] = tests + +print(json.dumps(result, sort_keys=True)) diff --git a/test/elixir/test/config/search.elixir b/test/elixir/test/config/search.elixir index 7d328c112..20e26682e 100644 --- a/test/elixir/test/config/search.elixir +++ b/test/elixir/test/config/search.elixir @@ -31,7 +31,8 @@ "facet counts, non-empty", "facet counts, empty", "facet ranges, empty", - "facet ranges, non-empty" + "facet ranges, non-empty", + "timeouts do not expose internal state" ], "ElemMatchTests": [ "elem match non object" diff --git a/test/elixir/test/config/skip.elixir b/test/elixir/test/config/skip.elixir index be427a740..1e0bec4df 100644 --- a/test/elixir/test/config/skip.elixir +++ b/test/elixir/test/config/skip.elixir @@ -1,26 +1,16 @@ %{ - "CookieAuthTest": [ - "cookie auth" - ], - "ReaderACLTest": [ - "unrestricted db can be read" - ], - "ReplicationTest": [ - "non-admin user on target - remote-to-remote", - "non-admin or reader user on source - remote-to-remote", - "unauthorized replication cancellation" - ], - "SecurityValidationTest": [ - "Author presence and user security when replicated" - ], - "WithQuorumTest": [ - "Creating/Deleting DB should return 201-Created/202-Acepted" + "JwtRolesClaimTest": [ + "case: roles_claim_name (defined) / roles_claim_path (defined)", + "case: roles_claim_name (defined) / roles_claim_path (undefined)", + "case: roles_claim_name (undefined) / roles_claim_path (defined)", + "case: roles_claim_name (undefined) / roles_claim_path (undefined)", + "case: roles_claim_path with bad input" ], "WithoutQuorumTest": [ - "Attachments should return 202-Acepted", - "Bulk docs should return 202-Acepted", - "Copy doc should return 202-Acepted", - "Creating/Deleting DB should return 202-Acepted", - "Creating/Updating/Deleting doc should return 202-Acepted" + "Attachments should return 202-Accepted", + "Bulk docs should return 202-Accepted", + "Copy doc should return 202-Accepted", + "Creating/Deleting DB should return 202-Accepted", + "Creating/Updating/Deleting doc should return 202-Accepted" ] } diff --git a/test/elixir/test/config/suite.elixir b/test/elixir/test/config/suite.elixir index 65e983f1d..a70909ef5 100644 --- a/test/elixir/test/config/suite.elixir +++ b/test/elixir/test/config/suite.elixir @@ -36,7 +36,6 @@ "etags for attachments", "implicit doc creation allows creating docs with a reserved id. COUCHDB-565", "large attachments COUCHDB-366", - "md5 header for attachments", "reads attachment successfully", "saves attachment successfully", "saves binary", @@ -48,7 +47,7 @@ ], "AuthLockoutTest": [ "lockout after multiple failed authentications", - "lockout warning after multiple failed authentications" + "do not lockout after multiple failed authentications" ], "BasicsTest": [ "'+' in document name should encode to '+'", @@ -156,7 +155,8 @@ "Only JSON strings are accepted" ], "CookieAuthTest": [ - "cookie auth" + "cookie auth", + "header doesn't contain set-cookie" ], "CopyDocTest": [ "Copy doc tests" @@ -257,6 +257,9 @@ "jwt auth with required iss claim", "jwt auth without secret" ], + "LargeDocsTest": [ + "Large docs" + ], "ListViewsTest": [ "COUCHDB-1113", "HTTP header response set after getRow() called in _list function", @@ -481,6 +484,9 @@ "split q=2 shards on node1 (2 jobs)", "toggle global state" ], + "ReshardChangesFeedTest": [ + "all_docs after splitting all shards on node1" + ], "RevStemmingTest": [ "revs limit is kept after compaction", "revs limit produces replication conflict ", @@ -493,8 +499,8 @@ "multiple updates with same _rev raise conflict errors" ], "RewriteJSTest": [ - "Test basic js rewrites on test_rewrite_suite_db", - "Test basic js rewrites on test_rewrite_suite_db%2Fwith_slashes", + "basic js rewrites on test_rewrite_suite_db", + "basic js rewrites on test_rewrite_suite_db%2Fwith_slashes", "early response on test_rewrite_suite_db", "early response on test_rewrite_suite_db%2Fwith_slashes", "loop on test_rewrite_suite_db", @@ -505,8 +511,8 @@ "requests with body preserve the query string rewrite on test_rewrite_suite_db%2Fwith_slashes" ], "RewriteTest": [ - "Test basic rewrites on test_rewrite_suite_db", - "Test basic rewrites on test_rewrite_suite_db%2Fwith_slashes", + "basic rewrites on test_rewrite_suite_db", + "basic rewrites on test_rewrite_suite_db%2Fwith_slashes", "loop detection on test_rewrite_suite_db", "loop detection on test_rewrite_suite_db%2Fwith_slashes", "path relative to server on test_rewrite_suite_db", @@ -643,7 +649,8 @@ "GET - invalid parameter combinations get rejected ", "POST - invalid parameter combinations get rejected ", "argument combinations", - "dir works", + "dir ascending works", + "dir descending works", "empty keys", "keys in GET body (group)", "keys in GET parameters", @@ -711,24 +718,24 @@ "view update seq" ], "WithQuorumTest": [ - "Attachments overriden quorum should return 202-Acepted", + "Attachments overridden quorum should return 202-Accepted", "Attachments should return 201-Created", - "Bulk docs overriden quorum should return 202-Acepted", + "Bulk docs overridden quorum should return 202-Accepted", "Bulk docs should return 201-Created", "Copy doc should return 201-Created", "Creating-Updating/Deleting doc should return 201-Created/200-OK", - "Creating-Updating/Deleting doc with overriden quorum should return 202-Acepted/200-OK", - "Creating/Deleting DB should return 201-Created/202-Acepted" + "Creating-Updating/Deleting doc with overridden quorum should return 202-Accepted/200-OK", + "Creating/Deleting DB should return 201-Created/202-Accepted" ], "WithoutQuorumTest": [ - "Attachments overriden quorum should return 201-Created", - "Attachments should return 202-Acepted", - "Bulk docs overriden quorum should return 201-Created", - "Bulk docs should return 202-Acepted", - "Copy doc should return 202-Acepted", - "Creating-Updating/Deleting doc with overriden quorum should return 201-Created/200-OK", - "Creating/Deleting DB should return 202-Acepted", - "Creating/Updating/Deleting doc should return 202-Acepted" + "Attachments overridden quorum should return 201-Created", + "Attachments should return 202-Accepted", + "Bulk docs overridden quorum should return 201-Created", + "Bulk docs should return 202-Accepted", + "Copy doc should return 202-Accepted", + "Creating-Updating/Deleting doc with overridden quorum should return 201-Created/200-OK", + "Creating/Deleting DB should return 202-Accepted", + "Creating/Updating/Deleting doc should return 202-Accepted" ], "BasicFindTest": [ "simple find", diff --git a/test/elixir/test/cookie_auth_test.exs b/test/elixir/test/cookie_auth_test.exs index cf9b36c7f..7cbac699f 100644 --- a/test/elixir/test/cookie_auth_test.exs +++ b/test/elixir/test/cookie_auth_test.exs @@ -374,45 +374,14 @@ defmodule CookieAuthTest do login("jan", "apple") end - test "basic+cookie auth interaction" do + test "header doesn't contain set-cookie" do # performing a successful basic authentication will create a session cookie resp = Couch.get( - "/_all_dbs", - no_auth: true, - headers: [authorization: "Basic #{:base64.encode("jan:apple")}"]) - assert resp.status_code == 200 - - # extract cookie value - cookie = resp.headers[:"set-cookie"] - [token | _] = String.split(cookie, ";") - - # Cookie is usable on its own - resp = Couch.get( - "/_session", - no_auth: true, - headers: [cookie: token]) - assert resp.status_code == 200 - assert resp.body["userCtx"]["name"] == "jan" - assert resp.body["info"]["authenticated"] == "cookie" + "/_all_dbs", + no_auth: true, + headers: [authorization: "Basic #{:base64.encode("jan:apple")}"]) - # Cookie is usable with basic auth if usernames match - resp = Couch.get( - "/_session", - no_auth: true, - headers: [ - authorization: "Basic #{:base64.encode("jan:apple")}", - cookie: token]) assert resp.status_code == 200 - assert resp.body["userCtx"]["name"] == "jan" - assert resp.body["info"]["authenticated"] == "cookie" - - # Cookie is not usable with basic auth if usernames don't match - resp = Couch.get( - "/_session", - no_auth: true, - headers: [ - authorization: "Basic #{:base64.encode("notjan:banana")}", - cookie: token]) - assert resp.status_code == 401 + assert resp.headers["set-cookie"] == nil end end diff --git a/test/elixir/test/disk_monitor.exs b/test/elixir/test/disk_monitor_test.exs similarity index 100% rename from test/elixir/test/disk_monitor.exs rename to test/elixir/test/disk_monitor_test.exs diff --git a/test/elixir/test/rewrite_js_test.exs b/test/elixir/test/rewrite_js_test.exs index a3adb3e7d..d793e616a 100644 --- a/test/elixir/test/rewrite_js_test.exs +++ b/test/elixir/test/rewrite_js_test.exs @@ -209,203 +209,200 @@ defmodule RewriteJSTest do } } - Enum.each( - ["test_rewrite_suite_db", "test_rewrite_suite_db%2Fwith_slashes"], - fn db_name -> - @tag with_random_db: db_name - test "Test basic js rewrites on #{db_name}", context do - db_name = context[:db_name] - - create_doc(db_name, @ddoc) - - docs1 = make_docs(0..9) - bulk_save(db_name, docs1) - - docs2 = [ - %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"}, - %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"}, - %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => "complex"}, - %{ - "a" => "test", - "b" => ["test", "essai"], - "string" => "doc 4", - "type" => "complex" - }, - %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => "complex"} - ] - - bulk_save(db_name, docs2) - - # Test simple rewriting - resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo") - assert resp.body == "This is a base64 encoded text" - assert resp.headers["Content-Type"] == "text/plain" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2") - assert resp.body == "This is a base64 encoded text" - assert resp.headers["Content-Type"] == "text/plain" - - # Test POST, hello update world - resp = - Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => "Rusty"}).body - - assert resp["ok"] - doc_id = resp["id"] - assert doc_id - - resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}") - assert resp.status_code in [201, 202] - assert resp.body == "hello doc" - assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) - - assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user") - assert resp.body == "Welcome user" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user") - assert resp.body == "Welcome user" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2") - assert resp.body == "Welcome user" - - resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test") - assert resp.status_code in [201, 202] - assert resp.body == "New World" - assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test") - assert resp.body == "Welcome test" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome4/user") - assert resp.body == "Welcome user" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome5/welcome3") - assert resp.body == "Welcome welcome3" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView") - assert resp.status_code == 200 - assert resp.body["total_rows"] == 9 - - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/FirstKey: [1, 2]/) - - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 3/) - - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 4/) - - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 5/) - - # COUCHDB-1612 - send body rewriting get to post - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/sendBody1") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 5 LineNo: 1/) - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true") - assert resp.status_code == 200 - assert resp.body["_id"] == "_design/test" - assert Map.has_key?(resp.body, "_revs_info") - end - - @tag with_random_db: db_name - test "early response on #{db_name}", context do - db_name = context[:db_name] - - ddoc = %{ - _id: "_design/response", - rewrites: """ - function(req){ - status = parseInt(req.query.status); - return {code: status, - body: JSON.stringify({"status": status}), - headers: {'x-foo': 'bar', 'Content-Type': 'application/json'}}; - } - """ + for db_name <- ["test_rewrite_suite_db", "test_rewrite_suite_db%2Fwith_slashes"] do + @tag with_random_db: db_name + test "basic js rewrites on #{db_name}", context do + db_name = context[:db_name] + + create_doc(db_name, @ddoc) + + docs1 = make_docs(0..9) + bulk_save(db_name, docs1) + + docs2 = [ + %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"}, + %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"}, + %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => "complex"}, + %{ + "a" => "test", + "b" => ["test", "essai"], + "string" => "doc 4", + "type" => "complex" + }, + %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => "complex"} + ] + + bulk_save(db_name, docs2) + + # Test simple rewriting + resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo") + assert resp.body == "This is a base64 encoded text" + assert resp.headers["Content-Type"] == "text/plain" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2") + assert resp.body == "This is a base64 encoded text" + assert resp.headers["Content-Type"] == "text/plain" + + # Test POST, hello update world + resp = + Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => "Rusty"}).body + + assert resp["ok"] + doc_id = resp["id"] + assert doc_id + + resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}") + assert resp.status_code in [201, 202] + assert resp.body == "hello doc" + assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) + + assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user") + assert resp.body == "Welcome user" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user") + assert resp.body == "Welcome user" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2") + assert resp.body == "Welcome user" + + resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test") + assert resp.status_code in [201, 202] + assert resp.body == "New World" + assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test") + assert resp.body == "Welcome test" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome4/user") + assert resp.body == "Welcome user" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome5/welcome3") + assert resp.body == "Welcome welcome3" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView") + assert resp.status_code == 200 + assert resp.body["total_rows"] == 9 + + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/FirstKey: [1, 2]/) + + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 3/) + + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 4/) + + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 5/) + + # COUCHDB-1612 - send body rewriting get to post + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/sendBody1") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 5 LineNo: 1/) + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true") + assert resp.status_code == 200 + assert resp.body["_id"] == "_design/test" + assert Map.has_key?(resp.body, "_revs_info") + end + + @tag with_random_db: db_name + test "early response on #{db_name}", context do + db_name = context[:db_name] + + ddoc = %{ + _id: "_design/response", + rewrites: """ + function(req){ + status = parseInt(req.query.status); + return {code: status, + body: JSON.stringify({"status": status}), + headers: {'x-foo': 'bar', 'Content-Type': 'application/json'}}; } + """ + } - create_doc(db_name, ddoc) + create_doc(db_name, ddoc) - resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=200") - assert resp.status_code == 200 - assert resp.headers["x-foo"] == "bar" - assert resp.body["status"] == 200 + resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=200") + assert resp.status_code == 200 + assert resp.headers["x-foo"] == "bar" + assert resp.body["status"] == 200 - resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=451") - assert resp.status_code == 451 - assert resp.headers["Content-Type"] == "application/json" + resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=451") + assert resp.status_code == 451 + assert resp.headers["Content-Type"] == "application/json" - resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=500") - assert resp.status_code == 500 - end + resp = Couch.get("/#{db_name}/_design/response/_rewrite?status=500") + assert resp.status_code == 500 + end - @tag with_random_db: db_name - test "path relative to server on #{db_name}", context do - db_name = context[:db_name] + @tag with_random_db: db_name + test "path relative to server on #{db_name}", context do + db_name = context[:db_name] - ddoc = %{ - _id: "_design/relative", - rewrites: """ - function(req){ - return '../../../_uuids' - } - """ + ddoc = %{ + _id: "_design/relative", + rewrites: """ + function(req){ + return '../../../_uuids' } + """ + } - create_doc(db_name, ddoc) - resp = Couch.get("/#{db_name}/_design/relative/_rewrite/uuids") - assert resp.status_code == 200 - assert length(resp.body["uuids"]) == 1 - end - - @tag with_random_db: db_name - test "loop on #{db_name}", context do - db_name = context[:db_name] - - ddoc_loop = %{ - _id: "_design/loop", - rewrites: """ - function(req) { - return '_rewrite/loop'; - } - """ + create_doc(db_name, ddoc) + resp = Couch.get("/#{db_name}/_design/relative/_rewrite/uuids") + assert resp.status_code == 200 + assert length(resp.body["uuids"]) == 1 + end + + @tag with_random_db: db_name + test "loop on #{db_name}", context do + db_name = context[:db_name] + + ddoc_loop = %{ + _id: "_design/loop", + rewrites: """ + function(req) { + return '_rewrite/loop'; } + """ + } - create_doc(db_name, ddoc_loop) - resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop") - assert resp.status_code == 400 - end + create_doc(db_name, ddoc_loop) + resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop") + assert resp.status_code == 400 + end - @tag with_random_db: db_name - test "requests with body preserve the query string rewrite on #{db_name}", - context do - db_name = context[:db_name] + @tag with_random_db: db_name + test "requests with body preserve the query string rewrite on #{db_name}", + context do + db_name = context[:db_name] - ddoc_qs = %{ - _id: "_design/qs", - rewrites: - "function (r) { return {path: '../../_changes', query: {'filter': '_doc_ids'}};};" - } + ddoc_qs = %{ + _id: "_design/qs", + rewrites: + "function (r) { return {path: '../../_changes', query: {'filter': '_doc_ids'}};};" + } - create_doc(db_name, ddoc_qs) - create_doc(db_name, %{_id: "qs1"}) - create_doc(db_name, %{_id: "qs2"}) + create_doc(db_name, ddoc_qs) + create_doc(db_name, %{_id: "qs1"}) + create_doc(db_name, %{_id: "qs2"}) - resp = - Couch.post("/#{db_name}/_design/qs/_rewrite", - body: %{doc_ids: ["qs2"]} - ) + resp = + Couch.post("/#{db_name}/_design/qs/_rewrite", + body: %{doc_ids: ["qs2"]} + ) - assert resp.status_code == 200 - assert length(resp.body["results"]) == 1 - assert Enum.at(resp.body["results"], 0)["id"] == "qs2" - end + assert resp.status_code == 200 + assert length(resp.body["results"]) == 1 + assert Enum.at(resp.body["results"], 0)["id"] == "qs2" end - ) + end end diff --git a/test/elixir/test/rewrite_test.exs b/test/elixir/test/rewrite_test.exs index 34fe3b7f5..4a13803c6 100644 --- a/test/elixir/test/rewrite_test.exs +++ b/test/elixir/test/rewrite_test.exs @@ -8,519 +8,522 @@ defmodule RewriteTest do This is a port of the rewrite.js suite """ - Enum.each( - ["test_rewrite_suite_db", "test_rewrite_suite_db%2Fwith_slashes"], - fn db_name -> - @tag with_random_db: db_name - @tag config: [ - {"httpd", "authentication_handlers", - "{couch_httpd_auth, special_test_authentication_handler}"}, - {"chttpd", "WWW-Authenticate", "X-Couch-Test-Auth"} - ] - test "Test basic rewrites on #{db_name}", context do - db_name = context[:db_name] - - ddoc = ~S""" - { - "_id": "_design/test", - "language": "javascript", - "_attachments": { - "foo.txt": { - "content_type":"text/plain", - "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=" + for db_name <- ["test_rewrite_suite_db", "test_rewrite_suite_db%2Fwith_slashes"] do + @tag with_random_db: db_name + @tag config: [ + {"httpd", "authentication_handlers", + "{couch_httpd_auth, special_test_authentication_handler}"}, + {"chttpd", "WWW-Authenticate", "X-Couch-Test-Auth"} + ] + test "basic rewrites on #{db_name}", context do + db_name = context[:db_name] + + ddoc = ~S""" + { + "_id": "_design/test", + "language": "javascript", + "_attachments": { + "foo.txt": { + "content_type":"text/plain", + "data": "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=" + } + }, + "rewrites": [ + { + "from": "foo", + "to": "foo.txt" + }, + { + "from": "foo2", + "to": "foo.txt", + "method": "GET" + }, + { + "from": "hello/:id", + "to": "_update/hello/:id", + "method": "PUT" + }, + { + "from": "/welcome", + "to": "_show/welcome" + }, + { + "from": "/welcome/:name", + "to": "_show/welcome", + "query": { + "name": ":name" } }, - "rewrites": [ - { - "from": "foo", - "to": "foo.txt" - }, - { - "from": "foo2", - "to": "foo.txt", - "method": "GET" - }, - { - "from": "hello/:id", - "to": "_update/hello/:id", - "method": "PUT" - }, - { - "from": "/welcome", - "to": "_show/welcome" - }, - { - "from": "/welcome/:name", - "to": "_show/welcome", - "query": { - "name": ":name" - } - }, - { - "from": "/welcome2", - "to": "_show/welcome", - "query": { - "name": "user" - } - }, - { - "from": "/welcome3/:name", - "to": "_update/welcome2/:name", - "method": "PUT" - }, - { - "from": "/welcome3/:name", - "to": "_show/welcome2/:name", - "method": "GET" - }, - { - "from": "/welcome4/*", - "to" : "_show/welcome3", - "query": { - "name": "*" - } - }, - { - "from": "/welcome5/*", - "to" : "_show/*", - "query": { - "name": "*" - } - }, - { - "from": "basicView", - "to": "_view/basicView" - }, - { - "from": "simpleForm/basicView", - "to": "_list/simpleForm/basicView" - }, - { - "from": "simpleForm/basicViewFixed", - "to": "_list/simpleForm/basicView", - "query": { - "startkey": 3, - "endkey": 8 - } - }, - { - "from": "simpleForm/basicViewPath/:start/:end", - "to": "_list/simpleForm/basicView", - "query": { - "startkey": ":start", - "endkey": ":end" - }, - "formats": { - "start": "int", - "end": "int" - } - }, - { - "from": "simpleForm/complexView", - "to": "_list/simpleForm/complexView", - "query": { - "key": [1, 2] - } - }, - { - "from": "simpleForm/complexView2", - "to": "_list/simpleForm/complexView", - "query": { - "key": ["test", {}] - } - }, - { - "from": "simpleForm/complexView3", - "to": "_list/simpleForm/complexView", - "query": { - "key": ["test", ["test", "essai"]] - } - }, - { - "from": "simpleForm/complexView4", - "to": "_list/simpleForm/complexView2", - "query": { - "key": {"c": 1} - } + { + "from": "/welcome2", + "to": "_show/welcome", + "query": { + "name": "user" + } + }, + { + "from": "/welcome3/:name", + "to": "_update/welcome2/:name", + "method": "PUT" + }, + { + "from": "/welcome3/:name", + "to": "_show/welcome2/:name", + "method": "GET" + }, + { + "from": "/welcome4/*", + "to" : "_show/welcome3", + "query": { + "name": "*" + } + }, + { + "from": "/welcome5/*", + "to" : "_show/*", + "query": { + "name": "*" + } + }, + { + "from": "basicView", + "to": "_view/basicView" + }, + { + "from": "simpleForm/basicView", + "to": "_list/simpleForm/basicView" + }, + { + "from": "simpleForm/basicViewFixed", + "to": "_list/simpleForm/basicView", + "query": { + "startkey": 3, + "endkey": 8 + } + }, + { + "from": "simpleForm/basicViewPath/:start/:end", + "to": "_list/simpleForm/basicView", + "query": { + "startkey": ":start", + "endkey": ":end" }, - { - "from": "simpleForm/complexView5/:a/:b", - "to": "_list/simpleForm/complexView3", - "query": { - "key": [":a", ":b"] - } + "formats": { + "start": "int", + "end": "int" + } + }, + { + "from": "simpleForm/complexView", + "to": "_list/simpleForm/complexView", + "query": { + "key": [1, 2] + } + }, + { + "from": "simpleForm/complexView2", + "to": "_list/simpleForm/complexView", + "query": { + "key": ["test", {}] + } + }, + { + "from": "simpleForm/complexView3", + "to": "_list/simpleForm/complexView", + "query": { + "key": ["test", ["test", "essai"]] + } + }, + { + "from": "simpleForm/complexView4", + "to": "_list/simpleForm/complexView2", + "query": { + "key": {"c": 1} + } + }, + { + "from": "simpleForm/complexView5/:a/:b", + "to": "_list/simpleForm/complexView3", + "query": { + "key": [":a", ":b"] + } + }, + { + "from": "simpleForm/complexView6", + "to": "_list/simpleForm/complexView3", + "query": { + "key": [":a", ":b"] + } + }, + { + "from": "simpleForm/complexView7/:a/:b", + "to": "_view/complexView3", + "query": { + "key": [":a", ":b"], + "include_docs": ":doc" }, - { - "from": "simpleForm/complexView6", - "to": "_list/simpleForm/complexView3", - "query": { - "key": [":a", ":b"] + "format": { + "doc": "bool" + } + + }, + { + "from": "/", + "to": "_view/basicView" + }, + { + "from": "/db/*", + "to": "../../*" + } + ], + "lists": { + "simpleForm": "function(head, req) { + log(\"simpleForm\"); + send(\"<ul>\"); + var row, row_number = 0, prevKey, firstKey = null; + while (row = getRow()) { + row_number += 1; + if (!firstKey) firstKey = row.key; + prevKey = row.key; + send(\"\\n<li>Key: \"+row.key + +\" Value: \"+row.value + +\" LineNo: \"+row_number+\"</li>\"); + } + return \"</ul><p>FirstKey: \"+ firstKey + \" LastKey: \"+ prevKey+\"</p>\"; + }" + }, + "shows": { + "welcome": "(function(doc,req) { + return \"Welcome \" + req.query[\"name\"]; + })", + "welcome2": "(function(doc, req) { + return \"Welcome \" + doc.name; + })", + "welcome3": "(function(doc,req) { + return \"Welcome \" + req.query[\"name\"]; + })" + }, + "updates": { + "hello" : "(function(doc, req) { + if (!doc) { + if (req.id) { + return [{ + _id : req.id + }, \"New World\"] } - }, - { - "from": "simpleForm/complexView7/:a/:b", - "to": "_view/complexView3", - "query": { - "key": [":a", ":b"], - "include_docs": ":doc" - }, - "format": { - "doc": "bool" + return [null, \"Empty World\"]; + } + doc.world = \"hello\"; + doc.edited_by = req.userCtx; + return [doc, \"hello doc\"]; + })", + "welcome2": "(function(doc, req) { + if (!doc) { + if (req.id) { + return [{ + _id: req.id, + name: req.id + }, \"New World\"] } - - }, - { - "from": "/", - "to": "_view/basicView" - }, - { - "from": "/db/*", - "to": "../../*" + return [null, \"Empty World\"]; } - ], - "lists": { - "simpleForm": "function(head, req) { - log(\"simpleForm\"); - send(\"<ul>\"); - var row, row_number = 0, prevKey, firstKey = null; - while (row = getRow()) { - row_number += 1; - if (!firstKey) firstKey = row.key; - prevKey = row.key; - send(\"\\n<li>Key: \"+row.key - +\" Value: \"+row.value - +\" LineNo: \"+row_number+\"</li>\"); + return [doc, \"hello doc\"]; + })" + }, + "views" : { + "basicView" : { + "map" : "(function(doc) { + if (doc.integer) { + emit(doc.integer, doc.string); } - return \"</ul><p>FirstKey: \"+ firstKey + \" LastKey: \"+ prevKey+\"</p>\"; - }" - }, - "shows": { - "welcome": "(function(doc,req) { - return \"Welcome \" + req.query[\"name\"]; - })", - "welcome2": "(function(doc, req) { - return \"Welcome \" + doc.name; - })", - "welcome3": "(function(doc,req) { - return \"Welcome \" + req.query[\"name\"]; + })" }, - "updates": { - "hello" : "(function(doc, req) { - if (!doc) { - if (req.id) { - return [{ - _id : req.id - }, \"New World\"] - } - return [null, \"Empty World\"]; + "complexView": { + "map": "(function(doc) { + if (doc.type == \"complex\") { + emit([doc.a, doc.b], doc.string); } - doc.world = \"hello\"; - doc.edited_by = req.userCtx; - return [doc, \"hello doc\"]; - })", - "welcome2": "(function(doc, req) { - if (!doc) { - if (req.id) { - return [{ - _id: req.id, - name: req.id - }, \"New World\"] - } - return [null, \"Empty World\"]; + })" + }, + "complexView2": { + "map": "(function(doc) { + if (doc.type == \"complex\") { + emit(doc.a, doc.string); } - return [doc, \"hello doc\"]; })" }, - "views" : { - "basicView" : { - "map" : "(function(doc) { - if (doc.integer) { - emit(doc.integer, doc.string); - } - - })" - }, - "complexView": { - "map": "(function(doc) { - if (doc.type == \"complex\") { - emit([doc.a, doc.b], doc.string); - } - })" - }, - "complexView2": { - "map": "(function(doc) { - if (doc.type == \"complex\") { - emit(doc.a, doc.string); - } - })" - }, - "complexView3": { - "map": "(function(doc) { - if (doc.type == \"complex\") { - emit(doc.b, doc.string); - } - })" - } + "complexView3": { + "map": "(function(doc) { + if (doc.type == \"complex\") { + emit(doc.b, doc.string); + } + })" } } - """ - - ddoc = String.replace(ddoc, ~r/[\r\n]+/, "") - - docs1 = make_docs(0..9) - - docs2 = [ - %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"}, - %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"}, - %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => "complex"}, - %{ - "a" => "test", - "b" => ["test", "essai"], - "string" => "doc 4", - "type" => "complex" - }, - %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => "complex"} - ] - - assert Couch.put("/#{db_name}/_design/test", body: ddoc).body["ok"] - - assert Couch.post( - "/#{db_name}/_bulk_docs", - body: %{:docs => docs1}, - query: %{w: 3} - ).status_code in [201, 202] - - assert Couch.post( - "/#{db_name}/_bulk_docs", - body: %{:docs => docs2}, - query: %{w: 3} - ).status_code in [201, 202] - - # Test simple rewriting - resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo") - assert resp.body == "This is a base64 encoded text" - assert resp.headers["Content-Type"] == "text/plain" - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2") - assert resp.body == "This is a base64 encoded text" - assert resp.headers["Content-Type"] == "text/plain" - - # Test POST, hello update world - resp = - Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => "Rusty"}).body - - assert resp["ok"] - doc_id = resp["id"] - assert doc_id - - resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}") - assert resp.status_code in [201, 202] - assert resp.body == "hello doc" - assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) + } + """ + + ddoc = String.replace(ddoc, ~r/[\r\n]+/, "") + + docs1 = make_docs(0..9) + + docs2 = [ + %{"a" => 1, "b" => 1, "string" => "doc 1", "type" => "complex"}, + %{"a" => 1, "b" => 2, "string" => "doc 2", "type" => "complex"}, + %{"a" => "test", "b" => %{}, "string" => "doc 3", "type" => "complex"}, + %{ + "a" => "test", + "b" => ["test", "essai"], + "string" => "doc 4", + "type" => "complex" + }, + %{"a" => %{"c" => 1}, "b" => "", "string" => "doc 5", "type" => "complex"} + ] + + assert Couch.put("/#{db_name}/_design/test", body: ddoc).body["ok"] + + assert Couch.post( + "/#{db_name}/_bulk_docs", + body: %{:docs => docs1}, + query: %{w: 3} + ).status_code in [201, 202] + + assert Couch.post( + "/#{db_name}/_bulk_docs", + body: %{:docs => docs2}, + query: %{w: 3} + ).status_code in [201, 202] + + # Test simple rewriting + resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo") + assert resp.body == "This is a base64 encoded text" + assert resp.headers["Content-Type"] == "text/plain" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo2") + assert resp.body == "This is a base64 encoded text" + assert resp.headers["Content-Type"] == "text/plain" + + # Test POST, hello update world + resp = + Couch.post("/#{db_name}", body: %{"word" => "plankton", "name" => "Rusty"}).body + + assert resp["ok"] + doc_id = resp["id"] + assert doc_id + + resp = Couch.put("/#{db_name}/_design/test/_rewrite/hello/#{doc_id}") + assert resp.status_code in [201, 202] + assert resp.body == "hello doc" + assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) + + assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user") + assert resp.body == "Welcome user" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user") + assert resp.body == "Welcome user" + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2") + assert resp.body == "Welcome user" + + resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test") + assert resp.status_code in [201, 202] + assert resp.body == "New World" + assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test") + assert resp.body == "Welcome test" - assert Couch.get("/#{db_name}/#{doc_id}").body["world"] == "hello" + # TODO: port the two "bugged" tests from rewrite.js + + resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView") + assert resp.status_code == 200 + assert resp.body["total_rows"] == 9 + + resp = Couch.get("/#{db_name}/_design/test/_rewrite") + assert resp.status_code == 200 + assert resp.body["total_rows"] == 9 + + resp = + Rawresp.get( + "/#{db_name}/_design/test/_rewrite/simpleForm/basicView?startkey=3&endkey=8" + ) + + assert resp.status_code == 200 + assert not String.match?(resp.body, ~r/Key: 1/) + assert String.match?(resp.body, ~r/FirstKey: 3/) + assert String.match?(resp.body, ~r/LastKey: 8/) + + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed") + assert resp.status_code == 200 + assert not String.match?(resp.body, ~r/Key: 1/) + assert String.match?(resp.body, ~r/FirstKey: 3/) + assert String.match?(resp.body, ~r/LastKey: 8/) + + resp = + Rawresp.get( + "/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed?startkey=4" + ) + + assert resp.status_code == 200 + assert not String.match?(resp.body, ~r/Key: 1/) + assert String.match?(resp.body, ~r/FirstKey: 3/) + assert String.match?(resp.body, ~r/LastKey: 8/) + + resp = + Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewPath/3/8") + + assert resp.status_code == 200 + assert not String.match?(resp.body, ~r/Key: 1/) + assert String.match?(resp.body, ~r/FirstKey: 3/) + assert String.match?(resp.body, ~r/LastKey: 8/) - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome?name=user") - assert resp.body == "Welcome user" + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/FirstKey: [1, 2]/) - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome/user") - assert resp.body == "Welcome user" + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 3/) - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome2") - assert resp.body == "Welcome user" + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 4/) - resp = Couch.put("/#{db_name}/_design/test/_rewrite/welcome3/test") - assert resp.status_code in [201, 202] - assert resp.body == "New World" - assert String.match?(resp.headers["Content-Type"], ~r/charset=utf-8/) + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4") + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 5/) - resp = Couch.get("/#{db_name}/_design/test/_rewrite/welcome3/test") - assert resp.body == "Welcome test" + resp = + Rawresp.get( + "/#{db_name}/_design/test/_rewrite/simpleForm/complexView5/test/essai" + ) - # TODO: port the two "bugged" tests from rewrite.js - - resp = Couch.get("/#{db_name}/_design/test/_rewrite/basicView") - assert resp.status_code == 200 - assert resp.body["total_rows"] == 9 - - resp = Couch.get("/#{db_name}/_design/test/_rewrite") - assert resp.status_code == 200 - assert resp.body["total_rows"] == 9 + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 4/) - resp = - Rawresp.get( - "/#{db_name}/_design/test/_rewrite/simpleForm/basicView?startkey=3&endkey=8" - ) + resp = + Rawresp.get( + "/#{db_name}/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai" + ) - assert resp.status_code == 200 - assert not String.match?(resp.body, ~r/Key: 1/) - assert String.match?(resp.body, ~r/FirstKey: 3/) - assert String.match?(resp.body, ~r/LastKey: 8/) + assert resp.status_code == 200 + assert String.match?(resp.body, ~r/Value: doc 4/) - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed") - assert resp.status_code == 200 - assert not String.match?(resp.body, ~r/Key: 1/) - assert String.match?(resp.body, ~r/FirstKey: 3/) - assert String.match?(resp.body, ~r/LastKey: 8/) + resp = + Rawresp.get( + "/#{db_name}/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true" + ) - resp = - Rawresp.get( - "/#{db_name}/_design/test/_rewrite/simpleForm/basicViewFixed?startkey=4" - ) + assert resp.status_code == 200 - assert resp.status_code == 200 - assert not String.match?(resp.body, ~r/Key: 1/) - assert String.match?(resp.body, ~r/FirstKey: 3/) - assert String.match?(resp.body, ~r/LastKey: 8/) + result = + resp.body |> IO.iodata_to_binary() |> :jiffy.decode([:return_maps, :use_nil]) - resp = - Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicViewPath/3/8") + first_row = Enum.at(result["rows"], 0) + assert Map.has_key?(first_row, "doc") - assert resp.status_code == 200 - assert not String.match?(resp.body, ~r/Key: 1/) - assert String.match?(resp.body, ~r/FirstKey: 3/) - assert String.match?(resp.body, ~r/LastKey: 8/) + # COUCHDB-2031 - path normalization versus qs params + resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true") + assert resp.status_code == 200 - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/FirstKey: [1, 2]/) + result = + resp.body |> IO.iodata_to_binary() |> :jiffy.decode([:return_maps, :use_nil]) - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView2") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 3/) + assert result["_id"] == "_design/test" + assert Map.has_key?(result, "_revs_info") - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView3") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 4/) + ddoc2 = %{ + _id: "_design/test2", + rewrites: [ + %{ + from: "uuids", + to: "../../../_uuids" + } + ] + } - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/simpleForm/complexView4") - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 5/) + create_doc(db_name, ddoc2) + resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids") + assert resp.status_code == 500 + assert resp.body["error"] == "insecure_rewrite_rule" + end - resp = - Rawresp.get( - "/#{db_name}/_design/test/_rewrite/simpleForm/complexView5/test/essai" - ) + @tag with_random_db: db_name + @tag config: [ + {"chttpd", "secure_rewrites", "false"} + ] + test "path relative to server on #{db_name}", context do + db_name = context[:db_name] - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 4/) + ddoc = %{ + _id: "_design/test2", + rewrites: [ + %{ + from: "uuids", + to: "../../../_uuids" + } + ] + } - resp = - Rawresp.get( - "/#{db_name}/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai" - ) + create_doc(db_name, ddoc) - assert resp.status_code == 200 - assert String.match?(resp.body, ~r/Value: doc 4/) + resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids") + assert resp.status_code == 200 + assert length(resp.body["uuids"]) == 1 + end - resp = - Rawresp.get( - "/#{db_name}/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true" - ) + @tag with_random_db: db_name + @tag config: [ + {"chttpd", "rewrite_limit", "2"} + ] + test "loop detection on #{db_name}", context do + db_name = context[:db_name] - assert resp.status_code == 200 - result = resp.body |> IO.iodata_to_binary() |> :jiffy.decode([:return_maps, :use_nil]) - first_row = Enum.at(result["rows"], 0) - assert Map.has_key?(first_row, "doc") + ddoc_loop = %{ + _id: "_design/loop", + rewrites: [%{from: "loop", to: "_rewrite/loop"}] + } - # COUCHDB-2031 - path normalization versus qs params - resp = Rawresp.get("/#{db_name}/_design/test/_rewrite/db/_design/test?meta=true") - assert resp.status_code == 200 - result = resp.body |> IO.iodata_to_binary() |> :jiffy.decode([:return_maps, :use_nil]) - assert result["_id"] == "_design/test" - assert Map.has_key?(result, "_revs_info") - - ddoc2 = %{ - _id: "_design/test2", - rewrites: [ - %{ - from: "uuids", - to: "../../../_uuids" - } - ] - } + create_doc(db_name, ddoc_loop) - create_doc(db_name, ddoc2) - resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids") - assert resp.status_code == 500 - assert resp.body["error"] == "insecure_rewrite_rule" - end + resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop") + assert resp.status_code == 400 + end - @tag with_random_db: db_name - @tag config: [ - {"chttpd", "secure_rewrites", "false"} - ] - test "path relative to server on #{db_name}", context do - db_name = context[:db_name] - - ddoc = %{ - _id: "_design/test2", - rewrites: [ - %{ - from: "uuids", - to: "../../../_uuids" - } - ] - } + @tag with_random_db: db_name + @tag config: [ + {"chttpd", "rewrite_limit", "2"}, + {"chttpd", "secure_rewrites", "false"} + ] + test "serial execution is not spuriously counted as loop on #{db_name}", context do + db_name = context[:db_name] + + ddoc = %{ + _id: "_design/test", + language: "javascript", + _attachments: %{ + "foo.txt": %{ + content_type: "text/plain", + data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=" + } + }, + rewrites: [ + %{ + from: "foo", + to: "foo.txt" + } + ] + } - create_doc(db_name, ddoc) + create_doc(db_name, ddoc) - resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids") + for _i <- 0..4 do + resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo") assert resp.status_code == 200 - assert length(resp.body["uuids"]) == 1 - end - - @tag with_random_db: db_name - @tag config: [ - {"chttpd", "rewrite_limit", "2"} - ] - test "loop detection on #{db_name}", context do - db_name = context[:db_name] - - ddoc_loop = %{ - _id: "_design/loop", - rewrites: [%{from: "loop", to: "_rewrite/loop"}] - } - - create_doc(db_name, ddoc_loop) - - resp = Couch.get("/#{db_name}/_design/loop/_rewrite/loop") - assert resp.status_code == 400 - end - - @tag with_random_db: db_name - @tag config: [ - {"chttpd", "rewrite_limit", "2"}, - {"chttpd", "secure_rewrites", "false"} - ] - test "serial execution is not spuriously counted as loop on #{db_name}", context do - db_name = context[:db_name] - - ddoc = %{ - _id: "_design/test", - language: "javascript", - _attachments: %{ - "foo.txt": %{ - content_type: "text/plain", - data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=" - } - }, - rewrites: [ - %{ - from: "foo", - to: "foo.txt" - } - ] - } - - create_doc(db_name, ddoc) - - for _i <- 0..4 do - resp = Couch.get("/#{db_name}/_design/test/_rewrite/foo") - assert resp.status_code == 200 - end end end - ) + end end
