diff options
author | Juanjo Rodriguez <juanjo@apache.org> | 2020-07-23 08:26:36 +0200 |
---|---|---|
committer | Juanjo Rodriguez <jjrodrig@gmail.com> | 2020-10-01 22:30:13 +0200 |
commit | 0494f0ef78ef668b68e22bca89dfd144e59592a3 (patch) | |
tree | 258dddb1f7f30a93200bdb0f64b4c57cc1e4218e | |
parent | a3ba88c897bba601dcab7d82999783a8c123c7fa (diff) | |
download | couchdb-0494f0ef78ef668b68e22bca89dfd144e59592a3.tar.gz |
port rewrite and rewrite_js tests into elixir
-rw-r--r-- | test/elixir/README.md | 2 | ||||
-rw-r--r-- | test/elixir/lib/couch_raw.ex | 105 | ||||
-rw-r--r-- | test/elixir/test/changes_async_test.exs | 103 | ||||
-rw-r--r-- | test/elixir/test/rewrite_js_test.exs | 411 | ||||
-rw-r--r-- | test/elixir/test/rewrite_test.exs | 181 | ||||
-rw-r--r-- | test/javascript/tests/rewrite.js | 2 | ||||
-rw-r--r-- | test/javascript/tests/rewrite_js.js | 3 |
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()) { |