summaryrefslogtreecommitdiff
path: root/test/elixir/test/rewrite_js_test.exs
diff options
context:
space:
mode:
Diffstat (limited to 'test/elixir/test/rewrite_js_test.exs')
-rw-r--r--test/elixir/test/rewrite_js_test.exs411
1 files changed, 411 insertions, 0 deletions
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