You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ji...@apache.org on 2025/12/10 21:37:05 UTC
(couchdb) branch fix-suite.elixir created (now a771da106)
This is an automated email from the ASF dual-hosted git repository.
jiahuili430 pushed a change to branch fix-suite.elixir
in repository https://gitbox.apache.org/repos/asf/couchdb.git
at a771da106 Modify suite.elixir
This branch includes the following new commits:
new a771da106 Modify suite.elixir
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(couchdb) 01/01: Modify suite.elixir
Posted by ji...@apache.org.
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 <li...@gmail.com>
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