summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuanjo Rodriguez <juanjo@apache.org>2020-07-23 08:26:36 +0200
committerJuanjo Rodriguez <jjrodrig@gmail.com>2020-10-01 22:30:13 +0200
commit0494f0ef78ef668b68e22bca89dfd144e59592a3 (patch)
tree258dddb1f7f30a93200bdb0f64b4c57cc1e4218e
parenta3ba88c897bba601dcab7d82999783a8c123c7fa (diff)
downloadcouchdb-0494f0ef78ef668b68e22bca89dfd144e59592a3.tar.gz
port rewrite and rewrite_js tests into elixir
-rw-r--r--test/elixir/README.md2
-rw-r--r--test/elixir/lib/couch_raw.ex105
-rw-r--r--test/elixir/test/changes_async_test.exs103
-rw-r--r--test/elixir/test/rewrite_js_test.exs411
-rw-r--r--test/elixir/test/rewrite_test.exs181
-rw-r--r--test/javascript/tests/rewrite.js2
-rw-r--r--test/javascript/tests/rewrite_js.js3
7 files changed, 691 insertions, 116 deletions
diff --git a/test/elixir/README.md b/test/elixir/README.md
index e30380904..0ef0d03ab 100644
--- a/test/elixir/README.md
+++ b/test/elixir/README.md
@@ -89,7 +89,7 @@ X means done, - means partially
- [ ] Port replicator_db_write_auth.js
- [X] Port rev_stemming.js
- [X] Port rewrite.js
- - [ ] Port rewrite_js.js
+ - [X] Port rewrite_js.js
- [X] Port security_validation.js
- [ ] Port show_documents.js
- [ ] Port stats.js
diff --git a/test/elixir/lib/couch_raw.ex b/test/elixir/lib/couch_raw.ex
new file mode 100644
index 000000000..62a0bbd0e
--- /dev/null
+++ b/test/elixir/lib/couch_raw.ex
@@ -0,0 +1,105 @@
+defmodule Rawresp do
+ use HTTPotion.Base
+
+ @moduledoc """
+ HTTP client that provides raw response as result
+ """
+ @request_timeout 60_000
+ @inactivity_timeout 55_000
+
+ def process_url("http://" <> _ = url) do
+ url
+ end
+
+ def process_url(url) do
+ base_url = System.get_env("EX_COUCH_URL") || "http://127.0.0.1:15984"
+ base_url <> url
+ end
+
+ def process_request_headers(headers, _body, options) do
+ headers =
+ headers
+ |> Keyword.put(:"User-Agent", "couch-potion")
+
+ headers =
+ if headers[:"Content-Type"] do
+ headers
+ else
+ Keyword.put(headers, :"Content-Type", "application/json")
+ end
+
+ case Keyword.get(options, :cookie) do
+ nil ->
+ headers
+
+ cookie ->
+ Keyword.put(headers, :Cookie, cookie)
+ end
+ end
+
+ def process_options(options) do
+ options
+ |> set_auth_options()
+ |> set_inactivity_timeout()
+ |> set_request_timeout()
+ end
+
+ def process_request_body(body) do
+ if is_map(body) do
+ :jiffy.encode(body)
+ else
+ body
+ end
+ end
+
+ def set_auth_options(options) do
+ if Keyword.get(options, :cookie) == nil do
+ headers = Keyword.get(options, :headers, [])
+
+ if headers[:basic_auth] != nil or headers[:authorization] != nil do
+ options
+ else
+ username = System.get_env("EX_USERNAME") || "adm"
+ password = System.get_env("EX_PASSWORD") || "pass"
+ Keyword.put(options, :basic_auth, {username, password})
+ end
+ else
+ options
+ end
+ end
+
+ def set_inactivity_timeout(options) do
+ Keyword.update(
+ options,
+ :ibrowse,
+ [{:inactivity_timeout, @inactivity_timeout}],
+ fn ibrowse ->
+ Keyword.put_new(ibrowse, :inactivity_timeout, @inactivity_timeout)
+ end
+ )
+ end
+
+ def set_request_timeout(options) do
+ timeout = Application.get_env(:httpotion, :default_timeout, @request_timeout)
+ Keyword.put_new(options, :timeout, timeout)
+ end
+
+ def login(userinfo) do
+ [user, pass] = String.split(userinfo, ":", parts: 2)
+ login(user, pass)
+ end
+
+ def login(user, pass, expect \\ :success) do
+ resp = Couch.post("/_session", body: %{:username => user, :password => pass})
+
+ if expect == :success do
+ true = resp.body["ok"]
+ cookie = resp.headers[:"set-cookie"]
+ [token | _] = String.split(cookie, ";")
+ %Couch.Session{cookie: token}
+ else
+ true = Map.has_key?(resp.body, "error")
+ %Couch.Session{error: resp.body["error"]}
+ end
+ end
+end
diff --git a/test/elixir/test/changes_async_test.exs b/test/elixir/test/changes_async_test.exs
index 07afcdc7c..6c833d433 100644
--- a/test/elixir/test/changes_async_test.exs
+++ b/test/elixir/test/changes_async_test.exs
@@ -440,106 +440,3 @@ defmodule ChangesAsyncTest do
create_doc(db_name, ddoc)
end
end
-
-defmodule Rawresp do
- use HTTPotion.Base
-
- @request_timeout 60_000
- @inactivity_timeout 55_000
-
- def process_url("http://" <> _ = url) do
- url
- end
-
- def process_url(url) do
- base_url = System.get_env("EX_COUCH_URL") || "http://127.0.0.1:15984"
- base_url <> url
- end
-
- def process_request_headers(headers, _body, options) do
- headers =
- headers
- |> Keyword.put(:"User-Agent", "couch-potion")
-
- headers =
- if headers[:"Content-Type"] do
- headers
- else
- Keyword.put(headers, :"Content-Type", "application/json")
- end
-
- case Keyword.get(options, :cookie) do
- nil ->
- headers
-
- cookie ->
- Keyword.put(headers, :Cookie, cookie)
- end
- end
-
- def process_options(options) do
- options
- |> set_auth_options()
- |> set_inactivity_timeout()
- |> set_request_timeout()
- end
-
- def process_request_body(body) do
- if is_map(body) do
- :jiffy.encode(body)
- else
- body
- end
- end
-
- def set_auth_options(options) do
- if Keyword.get(options, :cookie) == nil do
- headers = Keyword.get(options, :headers, [])
-
- if headers[:basic_auth] != nil or headers[:authorization] != nil do
- options
- else
- username = System.get_env("EX_USERNAME") || "adm"
- password = System.get_env("EX_PASSWORD") || "pass"
- Keyword.put(options, :basic_auth, {username, password})
- end
- else
- options
- end
- end
-
- def set_inactivity_timeout(options) do
- Keyword.update(
- options,
- :ibrowse,
- [{:inactivity_timeout, @inactivity_timeout}],
- fn ibrowse ->
- Keyword.put_new(ibrowse, :inactivity_timeout, @inactivity_timeout)
- end
- )
- end
-
- def set_request_timeout(options) do
- timeout = Application.get_env(:httpotion, :default_timeout, @request_timeout)
- Keyword.put_new(options, :timeout, timeout)
- end
-
- def login(userinfo) do
- [user, pass] = String.split(userinfo, ":", parts: 2)
- login(user, pass)
- end
-
- def login(user, pass, expect \\ :success) do
- resp = Couch.post("/_session", body: %{:username => user, :password => pass})
-
- if expect == :success do
- true = resp.body["ok"]
- cookie = resp.headers[:"set-cookie"]
- [token | _] = String.split(cookie, ";")
- %Couch.Session{cookie: token}
- else
- true = Map.has_key?(resp.body, "error")
- %Couch.Session{error: resp.body["error"]}
- end
- end
-end
diff --git a/test/elixir/test/rewrite_js_test.exs b/test/elixir/test/rewrite_js_test.exs
new file mode 100644
index 000000000..a3adb3e7d
--- /dev/null
+++ b/test/elixir/test/rewrite_js_test.exs
@@ -0,0 +1,411 @@
+defmodule RewriteJSTest do
+ use CouchTestCase
+
+ @moduletag :js_engine
+ @moduletag kind: :single_node
+
+ @moduledoc """
+ Test CouchDB rewrites JS
+ This is a port of the rewrite_js.js suite
+ """
+
+ @ddoc %{
+ _id: "_design/test",
+ language: "javascript",
+ _attachments: %{
+ "foo.txt": %{
+ content_type: "text/plain",
+ data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
+ }
+ },
+ rewrites: """
+ function(req) {
+ prefix = req.path[4];
+ if (prefix === 'foo') {
+ return 'foo.txt';
+ }
+ if (prefix === 'foo2') {
+ return {path: 'foo.txt', method: 'GET'};
+ }
+ if (prefix === 'hello') {
+ if (req.method != 'PUT') {
+ return
+ }
+ id = req.path[5];
+ return {path: '_update/hello/' + id};
+ }
+ if (prefix === 'welcome') {
+ if (req.path.length == 6){
+ name = req.path[5];
+ return {path: '_show/welcome', query: {'name': name}};
+ }
+ return '_show/welcome';
+ }
+ if (prefix === 'welcome2') {
+ return {path: '_show/welcome', query: {'name': 'user'}};
+ }
+ if (prefix === 'welcome3') {
+ name = req.path[5];
+ if (req.method == 'PUT') {
+ path = '_update/welcome2/' + name;
+ } else if (req.method == 'GET') {
+ path = '_show/welcome2/' + name;
+ } else {
+ return;
+ }
+ return path;
+ }
+ if (prefix === 'welcome4') {
+ return {path: '_show/welcome3', query: {name: req.path[5]}};
+ }
+ if (prefix === 'welcome5') {
+ rest = req.path.slice(5).join('/');
+ return {path: '_show/' + rest, query: {name: rest}};
+ }
+ if (prefix === 'basicView') {
+ rest = req.path.slice(5).join('/');
+ return {path: '_view/basicView'};
+ }
+ if (req.path.slice(4).join('/') === 'simpleForm/basicView') {
+ return {path: '_list/simpleForm/basicView'};
+ }
+ if (req.path.slice(4).join('/') === 'simpleForm/basicViewFixed') {
+ return {path: '_list/simpleForm/basicView',
+ query: {startkey: '"3"', endkey: '"8"'}};
+ }
+ if (req.path.slice(4).join('/') === 'simpleForm/complexView') {
+ return {path: '_list/simpleForm/complexView',
+ query: {key: JSON.stringify([1,2])}};
+ }
+ if (req.path.slice(4).join('/') === 'simpleForm/complexView2') {
+ return {path: '_list/simpleForm/complexView',
+ query: {key: JSON.stringify(['test', {}])}};
+ }
+ if (req.path.slice(4).join('/') === 'simpleForm/complexView3') {
+ return {path: '_list/simpleForm/complexView',
+ query: {key: JSON.stringify(['test', ['test', 'essai']])}};
+ }
+ if (req.path.slice(4).join('/') === 'simpleForm/complexView4') {
+ return {path: '_list/simpleForm/complexView2',
+ query: {key: JSON.stringify({"c": 1})}};
+ }
+ if (req.path.slice(4).join('/') === 'simpleForm/sendBody1') {
+ return {path: '_list/simpleForm/complexView2',
+ method: 'POST',
+ query: {limit: '1'},
+ headers:{'Content-type':'application/json'},
+ body: JSON.stringify( {keys: [{"c": 1}]} )};
+ }
+ if (req.path.slice(4).join('/') === '/') {
+ return {path: '_view/basicView'};
+ }
+ if (prefix === 'db') {
+ return {path: '../../' + req.path.slice(5).join('/')};
+ }
+ }
+ """,
+ lists: %{
+ simpleForm: """
+ function(head, req) {
+ 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"]
+ }
+ 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"]
+ }
+ return [null, "Empty World"];
+ }
+ 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);
+ }
+ }
+ """
+ }
+ }
+ }
+
+ 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'}};
+ }
+ """
+ }
+
+ 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=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
+
+ @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'
+ }
+ """
+ }
+
+ 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
+
+ @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'}};};"
+ }
+
+ 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"]}
+ )
+
+ 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 1960ddfde..30feac0ea 100644
--- a/test/elixir/test/rewrite_test.exs
+++ b/test/elixir/test/rewrite_test.exs
@@ -348,15 +348,178 @@ defmodule RewriteTest do
assert resp.status_code == 200
assert resp.body["total_rows"] == 9
- # TODO: port _list function tests and everything below in rewrite.js
- # This is currently broken because _list funcitons default to application/json
- # response bodies and my attempts to change the content-type from within the
- # _list function have not yet succeeded.
- #
- # Test GET with query params
- # resp = Couch.get("/#{db_name}/_design/test/_rewrite/simpleForm/basicView", query: %{startkey: 3, endkey: 8})
- # Logger.error("GOT RESP: #{inspect resp.body}")
- # assert resp.status_code == 200
+ 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 = 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/)
+
+ resp =
+ Rawresp.get(
+ "/#{db_name}/_design/test/_rewrite/simpleForm/complexView5/test/essai"
+ )
+
+ assert resp.status_code == 200
+ assert String.match?(resp.body, ~r/Value: doc 4/)
+
+ resp =
+ Rawresp.get(
+ "/#{db_name}/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai"
+ )
+
+ assert resp.status_code == 200
+ assert String.match?(resp.body, ~r/Value: doc 4/)
+
+ resp =
+ Rawresp.get(
+ "/#{db_name}/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true"
+ )
+
+ assert resp.status_code == 200
+ result = resp.body |> IO.iodata_to_binary() |> :jiffy.decode([:return_maps])
+ first_row = Enum.at(result["rows"], 0)
+ assert Map.has_key?(first_row, "doc")
+
+ # 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])
+ 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, ddoc2)
+ resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids")
+ assert resp.status_code == 500
+ assert resp.body["error"] == "insecure_rewrite_rule"
+ end
+
+ @tag with_random_db: db_name
+ @tag config: [
+ {"httpd", "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"
+ }
+ ]
+ }
+
+ create_doc(db_name, ddoc)
+
+ resp = Couch.get("/#{db_name}/_design/test2/_rewrite/uuids")
+ assert resp.status_code == 200
+ assert length(resp.body["uuids"]) == 1
+ end
+
+ @tag with_random_db: db_name
+ @tag config: [
+ {"httpd", "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: [
+ {"httpd", "rewrite_limit", "2"},
+ {"httpd", "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
)
diff --git a/test/javascript/tests/rewrite.js b/test/javascript/tests/rewrite.js
index a984936d1..88479b877 100644
--- a/test/javascript/tests/rewrite.js
+++ b/test/javascript/tests/rewrite.js
@@ -10,7 +10,7 @@
// License for the specific language governing permissions and limitations under
// the License.
-
+couchTests.elixir = true;
couchTests.rewrite = function(debug) {
if (debug) debugger;
diff --git a/test/javascript/tests/rewrite_js.js b/test/javascript/tests/rewrite_js.js
index 0ccdd6515..7179fc9f5 100644
--- a/test/javascript/tests/rewrite_js.js
+++ b/test/javascript/tests/rewrite_js.js
@@ -11,7 +11,7 @@
// the License.
-
+couchTests.elixir = true;
couchTests.rewrite = function(debug) {
if (debug) debugger;
var dbNames = [get_random_db_name(), get_random_db_name() + "test_suite_db/with_slashes"];
@@ -116,7 +116,6 @@ couchTests.rewrite = function(debug) {
}),
lists: {
simpleForm: stringFun(function(head, req) {
- log("simpleForm");
send('<ul>');
var row, row_number = 0, prevKey, firstKey = null;
while (row = getRow()) {