blob: 7179fc9f5b24ad85676609e6b61a2b9b091a3ea2 [file] [log] [blame]
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// 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"];
for (var i=0; i < dbNames.length; i++) {
var db = new CouchDB(dbNames[i]);
var dbName = encodeURIComponent(dbNames[i]);
db.deleteDb();
db.createDb();
var designDoc = {
_id:"_design/test",
language: "javascript",
_attachments:{
"foo.txt": {
content_type:"text/plain",
data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
}
},
rewrites: stringFun(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: stringFun(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": stringFun(function(doc,req) {
return "Welcome " + req.query["name"];
}),
"welcome2": stringFun(function(doc, req) {
return "Welcome " + doc.name;
}),
"welcome3": stringFun(function(doc,req) {
return "Welcome " + req.query["name"];
})
},
updates: {
"hello" : stringFun(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": stringFun(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 : stringFun(function(doc) {
if (doc.integer) {
emit(doc.integer, doc.string);
}
})
},
complexView: {
map: stringFun(function(doc) {
if (doc.type == "complex") {
emit([doc.a, doc.b], doc.string);
}
})
},
complexView2: {
map: stringFun(function(doc) {
if (doc.type == "complex") {
emit(doc.a, doc.string);
}
})
},
complexView3: {
map: stringFun(function(doc) {
if (doc.type == "complex") {
emit(doc.b, doc.string);
}
})
}
}
}
db.save(designDoc);
var docs = makeDocs(0, 10);
db.bulkSave(docs);
var 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"}
];
db.bulkSave(docs2);
// test simple rewriting
req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo");
T(req.responseText == "This is a base64 encoded text");
T(req.getResponseHeader("Content-Type") == "text/plain");
req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo2");
T(req.responseText == "This is a base64 encoded text");
T(req.getResponseHeader("Content-Type") == "text/plain");
// test POST
// hello update world
var doc = {"word":"plankton", "name":"Rusty"}
var resp = db.save(doc);
T(resp.ok);
var docid = resp.id;
xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/hello/"+docid);
T(xhr.status == 201);
T(xhr.responseText == "hello doc");
T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")))
doc = db.open(docid);
T(doc.world == "hello");
req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome?name=user");
T(req.responseText == "Welcome user");
req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome/user");
T(req.responseText == "Welcome user");
req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome2");
T(req.responseText == "Welcome user");
xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
T(xhr.status == 201);
T(xhr.responseText == "New World");
T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
T(xhr.responseText == "Welcome test");
req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome4/user");
T(req.responseText == "Welcome user");
req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome5/welcome3");
T(req.responseText == "Welcome welcome3");
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/basicView");
T(xhr.status == 200, "view call");
T(/{"total_rows":9/.test(xhr.responseText));
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView");
T(xhr.status == 200, "with query params");
T(/FirstKey: [1, 2]/.test(xhr.responseText));
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView2");
T(xhr.status == 200, "with query params");
T(/Value: doc 3/.test(xhr.responseText));
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView3");
T(xhr.status == 200, "with query params");
T(/Value: doc 4/.test(xhr.responseText));
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView4");
T(xhr.status == 200, "with query params");
T(/Value: doc 5/.test(xhr.responseText));
// COUCHDB-1612 - send body rewriting get to post
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/sendBody1");
T(xhr.status == 200, "get->post rewrite failed:\n"+xhr.responseText);
T(/Value: doc 5 LineNo: 1/.test(xhr.responseText), "get->post rewrite responded wrong:\n"+xhr.responseText);
// COUCHDB-2031 - path normalization versus qs params
xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/db/_design/test?meta=true");
T(xhr.status == 200, "path normalization works with qs params");
var result = JSON.parse(xhr.responseText);
T(result['_id'] == "_design/test");
T(typeof(result['_revs_info']) === "object");
// test early response
var ddoc = {
_id: "_design/response",
rewrites: stringFun(function(req){
status = parseInt(req.query.status);
return {code: status,
body: JSON.stringify({"status": status}),
headers: {'x-foo': 'bar', 'Content-Type': 'application/json'}};
})
}
T(db.save(ddoc).ok);
var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=200");
T(xhr.status == 200);
T(xhr.headers['x-foo'] == 'bar');
T(xhr.responseText == '{"status":200}');
var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=451");
T(xhr.status == 451);
T(xhr.headers['Content-Type'] == 'application/json');
var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=600");
T(xhr.status == 500);
// test path relative to server
var ddoc = {
_id: "_design/relative",
rewrites: stringFun(function(req){
return '../../../_uuids'
})
}
T(db.save(ddoc).ok);
var xhr = CouchDB.request("GET", "/"+dbName+"/_design/relative/_rewrite/uuids");
T(xhr.status == 200);
var result = JSON.parse(xhr.responseText);
T(result.uuids.length == 1);
// test loop
var ddoc_loop = {
_id: "_design/loop",
rewrites: stringFun(function(req) {
return '_rewrite/loop';
})
};
db.save(ddoc_loop);
var url = "/"+dbName+"/_design/loop/_rewrite/loop";
var xhr = CouchDB.request("GET", url);
TEquals(400, xhr.status);
// test requests with body preserve the query string rewrite
var ddoc_qs = {
"_id": "_design/qs",
"rewrites": "function (r) { return {path: '../../_changes', query: {'filter': '_doc_ids'}};};"
}
db.save(ddoc_qs);
db.save({"_id": "qs1", "foo": "bar"});
db.save({"_id": "qs2", "foo": "bar"});
var url = "/"+dbName+"/_design/qs/_rewrite";
var xhr = CouchDB.request("POST", url, {body: JSON.stringify({"doc_ids": ["qs2"]})});
var result = JSON.parse(xhr.responseText);
T(xhr.status == 200);
T(result.results.length == 1, "Only one doc is expected");
TEquals(result.results[0].id, "qs2");
// cleanup
db.deleteDb();
}
}