This is an automated email from the ASF dual-hosted git repository. jiahuili430 pushed a commit to branch fix-suite.elixir in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit a771da106db27499e2e450e55ddf6d3b566d4928 Author: Jiahui Li <[email protected]> AuthorDate: Wed Dec 10 14:31:57 2025 -0600 Modify suite.elixir --- test/elixir/test/config/suite.elixir => t.json | 291 ++++--- t.py | 25 + test/elixir/test/config/search.elixir | 3 +- test/elixir/test/config/suite.elixir | 24 +- .../{disk_monitor.exs => disk_monitor_test.exs} | 0 test/elixir/test/rewrite_js_test.exs | 361 ++++---- test/elixir/test/rewrite_test.exs | 937 +++++++++++---------- 7 files changed, 859 insertions(+), 782 deletions(-) diff --git a/test/elixir/test/config/suite.elixir b/t.json similarity index 83% copy from test/elixir/test/config/suite.elixir copy to t.json index 65e983f1d..f6384dab4 100644 --- a/test/elixir/test/config/suite.elixir +++ b/t.json @@ -1,4 +1,4 @@ -%{ +{ "AllDocsTest": [ "All Docs tests", "GET with one key", @@ -27,7 +27,8 @@ "manages attachments in views successfully" ], "AttachmentsTest": [ - "COUCHDB-809 - stubs should only require the 'stub' field", + "COUCHDB-497 - empty attachments", + "COUCHDB-809 - stubs should only require the ", "attachment via multipart/form-data", "delete attachment", "delete attachment request with a payload should not block following requests", @@ -36,23 +37,52 @@ "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", - "COUCHDB-497 - empty attachments", "update attachment" ], "AuthCacheTest": [ "auth cache management" ], "AuthLockoutTest": [ - "lockout after multiple failed authentications", - "lockout warning after multiple failed authentications" + "do not lockout after multiple failed authentications", + "lockout after multiple failed authentications" + ], + "BasicFindTest": [ + "bad conflicts", + "bad fields", + "bad limit", + "bad r", + "bad selector", + "bad skip", + "bad sort", + "empty", + "empty subsel", + "empty subsel match", + "explain options", + "explain view args", + "fields", + "limit", + "missing not indexed", + "multi col idx", + "multi cond and", + "multi cond duplicate field", + "multi cond or", + "r", + "simple find", + "skip", + "sort", + "sort desc complex", + "sort desc complex error", + "sort exists true", + "sort with all docs", + "sort with primary sort not in selector", + "unsatisfiable range" ], "BasicsTest": [ - "'+' in document name should encode to '+'", - "'+' in document name should encode to space", + "'+", + "'+", "A document read with etag works", "Can create several documents", "Check for invalid document members", @@ -60,17 +90,17 @@ "Created database has appropriate db info name", "Creating a new DB should return location header", "Creating a new DB with slashes should return Location header (COUCHDB-411)", - "DELETE'ing a non-existent doc should 404", - "Database name with '%2B' should encode to '+'", - "Database name with '+' should encode to '+'", + "DELETE", + "Database name with ", + "Database name with ", "Database should be in _all_dbs", - "Limit and skip should work in _all_dbs", "Default headers are returned for doc with open_revs=all", "Empty database should have zero docs", + "Limit and skip should work in _all_dbs", "Make sure you can do a seq=true option", "On restart, a request for creating an already existing db can not override", "POST doc response has a Location header", - "POST doc with an _id field isn't overwritten by uuid", + "POST doc with an _id field isn", "PUT doc has a Location header", "PUT error when body not an object", "PUT on existing DB should return 412 instead of 500", @@ -79,7 +109,7 @@ "Session contains adm context", "Simple map functions", "Welcome endpoint", - "_all_docs POST error when multi-get is not a {'key': [...]} structure", + "_all_docs POST error when multi-get is not a {", "_bulk_docs POST error when body not an object", "oops, the doc id got lost in code nirwana", "request ID can be specified at the client" @@ -106,11 +136,11 @@ "continuous filtered changes", "continuous filtered changes with doc ids", "eventsource changes", - "eventsource changes with limit under", "eventsource changes with limit exact", "eventsource changes with limit over", - "eventsource no junk in response", + "eventsource changes with limit under", "eventsource heartbeat", + "eventsource no junk in response", "live changes", "longpoll changes", "longpoll filtered changes" @@ -141,21 +171,22 @@ ], "ConfigTest": [ "Atoms, binaries, and strings suffice as whitelist sections and keys.", + "Auto-reload config", "Blacklist is functional", "CouchDB respects configured protocols", "Keys not in the whitelist may not be modified", "Non-2-tuples in the whitelist are ignored", "Non-list whitelist values allow further modification of the whitelist", "Non-term whitelist values allow further modification of the whitelist", + "Only JSON strings are accepted", "PORT `BUGGED` ?raw tests from config.js", "Reload config", - "Auto-reload config", "Server-side password hashing, and raw updates disabling that", "Settings can be altered with undefined whitelist allowing any change", - "Standard config options are present", - "Only JSON strings are accepted" + "Standard config options are present" ], "CookieAuthTest": [ + "basic+cookie auth interaction", "cookie auth" ], "CopyDocTest": [ @@ -203,15 +234,13 @@ "design doc options - include_desing=true", "design doc options - local_seq=true" ], - "DiskMonitorTest": [ - "block background view indexing", - "block interactive view indexing", - "block interactive database writes" - ], "DesignPathTest": [ "design doc path", "design doc path with slash in db name" ], + "ElemMatchTests": [ + "elem match non object" + ], "ErlangViewsTest": [ "Erlang map function", "Erlang reduce function", @@ -237,6 +266,9 @@ "location header should include X-Forwarded-Host", "location header should include custom header" ], + "IgnoreDesignDocsForAllDocsIndexTests": [ + "should not return design docs" + ], "InvalidDocIDsTest": [ "_local-prefixed ids are illegal", "a PUT request with absent _id is forbidden", @@ -257,6 +289,16 @@ "jwt auth with required iss claim", "jwt auth without secret" ], + "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" + ], + "LimitTests": [ + "limit field" + ], "ListViewsTest": [ "COUCHDB-1113", "HTTP header response set after getRow() called in _list function", @@ -297,13 +339,48 @@ "lots of docs with a regular view" ], "MethodOverrideTest": [ - "Method Override is ignored when original Method isn't POST", + "Method Override is ignored when original Method isn", "method override DELETE", "method override PUT" ], "MultipleRowsTest": [ "multiple rows" ], + "NouveauTest": [ + "counts", + "delete", + "index not found", + "index same field with different field types", + "mango (partitioned)", + "mango search by number", + "mango search by string", + "mango search by text", + "mango sort by number", + "mango sort by string", + "meta", + "multiple values for stored field", + "purge", + "purge with conflicts", + "ranges", + "ranges (open)", + "search GET (partitioned)", + "search POST (partitioned)", + "search analyze", + "search for foo:bar", + "search for numeric ranges with locales", + "search info", + "search returns all items (paginated)", + "search returns all items for GET", + "search returns all items for POST", + "search returns all matches for hello by relevance", + "sort by numeric field (asc)", + "sort by numeric field (desc)", + "sort by string field (asc)", + "sort by string field (desc)", + "stale search", + "top_n", + "user-agent header is forbidden" + ], "PartitionAllDocsTest": [ "all_docs with partitioned:true returns partitioned fields", "partition _all_docs with descending", @@ -374,6 +451,21 @@ "query using _id works for global and local query", "query with partitioned:true using index and $eq" ], + "PartitionSearchTest": [ + "Cannot do global query with partition view", + "Cannot do partition query with global search ddoc", + "Only returns docs in partition not those in shard", + "Simple query returns partitioned search results", + "Works with bookmarks and limit", + "Works with limit using POST for on non-partitioned db", + "Works with limit using POST for partitioned db", + "normal search on non-partitioned dbs still work", + "normal search on non-partitioned dbs with limit", + "normal search on non-partitioned dbs with over limit", + "normal search on non-partitioned dbs without limit", + "rejects conflicting partition values", + "restricted parameters are not allowed in query or body" + ], "PartitionSizeLimitTest": [ "compacting a full partition works", "decreasing partition size disables more writes", @@ -394,7 +486,7 @@ ], "PartitionSizeTest": [ "adding docs increases partition sizes", - "attachments don't affect other partitions", + "attachments don", "deleting a doc affects partition sizes", "design docs do not affect partition sizes", "get all partition sizes", @@ -403,7 +495,7 @@ "partition activity not affect other partition sizes", "purging docs decreases partition size", "simple partition size", - "unknown partition return's zero", + "unknown partition return", "updating docs affects partition sizes" ], "PartitionViewUpdateTest": [ @@ -413,7 +505,7 @@ "view updates properly remove old keys" ], "PasswordCacheTest": [ - "password cache" + "password hash cache" ], "ProxyAuthTest": [ "proxy auth with secret", @@ -424,7 +516,7 @@ "purge documents" ], "ReaderACLTest": [ - "can't set non string reader names or roles", + "can", "members can query views", "restricted db can be read by authorized users", "unrestricted db can be read", @@ -452,23 +544,23 @@ "Reduce pagination" ], "ReplicationTest": [ - "compressed attachment replication - remote-to-remote", - "continuous replication - remote-to-remote", - "create_target filter option - remote-to-remote", + "compressed attachment replication - #{name}", + "continuous replication - #{name}", + "create_target filter option - #{name}", "default headers returned for _scheduler/docs ", "default headers returned for _scheduler/jobs", - "filtered replications - remote-to-remote", - "non-admin or reader user on source - remote-to-remote", - "non-admin user on target - remote-to-remote", - "replicate with since_seq - remote-to-remote", + "filtered replications - #{name}", + "non-admin or reader user on source - #{name}", + "non-admin user on target - #{name}", + "replicate with since_seq - #{name}", "replicating attachment without conflict - COUCHDB-885", - "replication by doc ids - remote-to-remote", + "replication by doc ids - #{name}", "replication cancellation", - "replication restarts after filter change - COUCHDB-892 - remote-to-remote", - "simple remote-to-remote replication - remote-to-remote", + "replication restarts after filter change - COUCHDB-892 - #{name}", + "simple #{name} replication - #{name}", "source database not found with host", "unauthorized replication cancellation", - "validate_doc_update failure replications - remote-to-remote" + "validate_doc_update failure replications - #{name}" ], "ReshardAllDocsTest": [ "all_docs after splitting all shards on node1", @@ -493,26 +585,37 @@ "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", - "early response on test_rewrite_suite_db", - "early response on test_rewrite_suite_db%2Fwith_slashes", - "loop on test_rewrite_suite_db", - "loop on test_rewrite_suite_db%2Fwith_slashes", - "path relative to server on test_rewrite_suite_db", - "path relative to server on test_rewrite_suite_db%2Fwith_slashes", - "requests with body preserve the query string rewrite on test_rewrite_suite_db", - "requests with body preserve the query string rewrite on test_rewrite_suite_db%2Fwith_slashes" + "Test basic js rewrites on #{db_name}", + "early response on #{db_name}", + "loop on #{db_name}", + "path relative to server on #{db_name}", + "requests with body preserve the query string rewrite on #{db_name}" ], "RewriteTest": [ - "Test basic rewrites on test_rewrite_suite_db", - "Test 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", - "path relative to server on test_rewrite_suite_db%2Fwith_slashes", - "serial execution is not spuriously counted as loop on test_rewrite_suite_db", - "serial execution is not spuriously counted as loop on test_rewrite_suite_db%2Fwith_slashes" + "Test basic rewrites on #{db_name}", + "loop detection on #{db_name}", + "path relative to server on #{db_name}", + "serial execution is not spuriously counted as loop on #{db_name}" + ], + "SearchTest": [ + "clean up search index with invalid design document", + "drilldown multiple keys multiple values for POST", + "drilldown multiple keys single values for GET", + "drilldown multiple keys single values for POST", + "drilldown multiple query definitions for GET", + "drilldown multiple query definitions for POST", + "drilldown single key multiple values for GET", + "drilldown single key multiple values for POST", + "drilldown single key single value for GET", + "drilldown single key single value for POST", + "drilldown three keys single values for POST", + "facet counts, empty", + "facet counts, non-empty", + "facet ranges, empty", + "facet ranges, non-empty", + "search returns all items for GET", + "search returns all items for POST", + "timeouts do not expose internal state" ], "SecurityValidationTest": [ "Author presence and user security", @@ -526,7 +629,7 @@ "try to set a wrong value for _security" ], "ShowDocumentsTest": [ - "JS can't set etag", + "JS can", "accept header switching - different mime has different etag", "deleted docs", "id with slash", @@ -625,8 +728,8 @@ "no reduce support" ], "ViewMultiKeyAllDocsTest": [ - "GET - get invalid rows when the key doesn't exist", - "POST - get invalid rows when the key doesn't exist", + "GET - get invalid rows when the key doesn", + "POST - get invalid rows when the key doesn", "empty keys", "keys in GET parameters", "keys in GET parameters (descending)", @@ -643,7 +746,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", @@ -689,7 +793,7 @@ "view query returns all docs for global query" ], "ViewSandboxingTest": [ - "COUCHDB-925 - altering 'doc' variable in map function affects other map functions", + "COUCHDB-925 - altering ", "attempting to change the document has no effect", "runtime code evaluation can be prevented", "view cannot access the map_funs and map_results array", @@ -729,66 +833,5 @@ "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" - ], - "BasicFindTest": [ - "simple find", - "bad selector", - "bad limit", - "bad skip", - "bad sort", - "bad fields", - "bad r", - "bad conflicts", - "multi cond and", - "multi cond duplicate field", - "multi cond or", - "multi col idx", - "missing not indexed", - "limit", - "skip", - "sort", - "sort desc complex", - "sort with primary sort not in selector", - "sort exists true", - "sort desc complex error", - "fields", - "r", - "empty", - "empty subsel", - "empty subsel match", - "unsatisfiable range", - "explain view args", - "explain options", - "sort with all docs" - ], - "IgnoreDesignDocsForAllDocsIndexTests": [ - "should not return design docs" - ], - "JSONIndexSelectionTest": [ - "basic", - "with and", - "with nested and", - "with or", - "use most columns", - "no valid sort index", - "invalid use index", - "uses index when no range or equals", - "reject use index invalid fields", - "reject use index ddoc and name invalid fields", - "reject use index sort order", - "use index fallback if valid sort", - "prefer use index over optimal index", - "manual bad view idx01", - "explain sort reverse", - "use index with invalid name", - "use index without fallback succeeds for valid index", - "use index without fallback fails for invalid index with fallback available", - "use index without fallback succeeds for empty index", - "use index without fallback fails for empty index", - "use index without fallback fails for invalid index no fallback exists", - "index without fallback", - "no index without fallback", - "uses all docs when fields do not match selector", - "uses all docs when selector doesnt require fields to exist" ] } diff --git a/t.py b/t.py new file mode 100644 index 000000000..ad9adb947 --- /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/suite.elixir b/test/elixir/test/config/suite.elixir index 65e983f1d..119640a49 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", + "basic+cookie auth interaction" ], "CopyDocTest": [ "Copy doc tests" @@ -257,6 +257,13 @@ "jwt auth with required iss claim", "jwt auth without secret" ], + "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" + ], "ListViewsTest": [ "COUCHDB-1113", "HTTP header response set after getRow() called in _list function", @@ -493,8 +500,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 +512,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 +650,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", 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
