PageRenderTime 65ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/test/javascript/tests/rewrite_js.js

http://github.com/apache/couchdb
JavaScript | 351 lines | 295 code | 36 blank | 20 comment | 74 complexity | 65ed8d374ee749ce7db94f43186bbcf2 MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0
  1. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  2. // use this file except in compliance with the License. You may obtain a copy of
  3. // the License at
  4. //
  5. // http://www.apache.org/licenses/LICENSE-2.0
  6. //
  7. // Unless required by applicable law or agreed to in writing, software
  8. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  9. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  10. // License for the specific language governing permissions and limitations under
  11. // the License.
  12. couchTests.rewrite = function(debug) {
  13. if (debug) debugger;
  14. var dbNames = [get_random_db_name(), get_random_db_name() + "test_suite_db/with_slashes"];
  15. for (var i=0; i < dbNames.length; i++) {
  16. var db = new CouchDB(dbNames[i]);
  17. var dbName = encodeURIComponent(dbNames[i]);
  18. db.deleteDb();
  19. db.createDb();
  20. var designDoc = {
  21. _id:"_design/test",
  22. language: "javascript",
  23. _attachments:{
  24. "foo.txt": {
  25. content_type:"text/plain",
  26. data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
  27. }
  28. },
  29. rewrites: stringFun(function(req) {
  30. prefix = req.path[4];
  31. if (prefix === 'foo') {
  32. return 'foo.txt';
  33. }
  34. if (prefix === 'foo2') {
  35. return {path: 'foo.txt', method: 'GET'};
  36. }
  37. if (prefix === 'hello') {
  38. if (req.method != 'PUT') {
  39. return
  40. }
  41. id = req.path[5];
  42. return {path: '_update/hello/' + id};
  43. }
  44. if (prefix === 'welcome') {
  45. if (req.path.length == 6){
  46. name = req.path[5];
  47. return {path: '_show/welcome', query: {'name': name}};
  48. }
  49. return '_show/welcome';
  50. }
  51. if (prefix === 'welcome2') {
  52. return {path: '_show/welcome', query: {'name': 'user'}};
  53. }
  54. if (prefix === 'welcome3') {
  55. name = req.path[5];
  56. if (req.method == 'PUT') {
  57. path = '_update/welcome2/' + name;
  58. } else if (req.method == 'GET') {
  59. path = '_show/welcome2/' + name;
  60. } else {
  61. return;
  62. }
  63. return path;
  64. }
  65. if (prefix === 'welcome4') {
  66. return {path: '_show/welcome3', query: {name: req.path[5]}};
  67. }
  68. if (prefix === 'welcome5') {
  69. rest = req.path.slice(5).join('/');
  70. return {path: '_show/' + rest, query: {name: rest}};
  71. }
  72. if (prefix === 'basicView') {
  73. rest = req.path.slice(5).join('/');
  74. return {path: '_view/basicView'};
  75. }
  76. if (req.path.slice(4).join('/') === 'simpleForm/basicView') {
  77. return {path: '_list/simpleForm/basicView'};
  78. }
  79. if (req.path.slice(4).join('/') === 'simpleForm/basicViewFixed') {
  80. return {path: '_list/simpleForm/basicView',
  81. query: {startkey: '"3"', endkey: '"8"'}};
  82. }
  83. if (req.path.slice(4).join('/') === 'simpleForm/complexView') {
  84. return {path: '_list/simpleForm/complexView',
  85. query: {key: JSON.stringify([1,2])}};
  86. }
  87. if (req.path.slice(4).join('/') === 'simpleForm/complexView2') {
  88. return {path: '_list/simpleForm/complexView',
  89. query: {key: JSON.stringify(['test', {}])}};
  90. }
  91. if (req.path.slice(4).join('/') === 'simpleForm/complexView3') {
  92. return {path: '_list/simpleForm/complexView',
  93. query: {key: JSON.stringify(['test', ['test', 'essai']])}};
  94. }
  95. if (req.path.slice(4).join('/') === 'simpleForm/complexView4') {
  96. return {path: '_list/simpleForm/complexView2',
  97. query: {key: JSON.stringify({"c": 1})}};
  98. }
  99. if (req.path.slice(4).join('/') === 'simpleForm/sendBody1') {
  100. return {path: '_list/simpleForm/complexView2',
  101. method: 'POST',
  102. query: {limit: '1'},
  103. headers:{'Content-type':'application/json'},
  104. body: JSON.stringify( {keys: [{"c": 1}]} )};
  105. }
  106. if (req.path.slice(4).join('/') === '/') {
  107. return {path: '_view/basicView'};
  108. }
  109. if (prefix === 'db') {
  110. return {path: '../../' + req.path.slice(5).join('/')};
  111. }
  112. }),
  113. lists: {
  114. simpleForm: stringFun(function(head, req) {
  115. log("simpleForm");
  116. send('<ul>');
  117. var row, row_number = 0, prevKey, firstKey = null;
  118. while (row = getRow()) {
  119. row_number += 1;
  120. if (!firstKey) firstKey = row.key;
  121. prevKey = row.key;
  122. send('\n<li>Key: '+row.key
  123. +' Value: '+row.value
  124. +' LineNo: '+row_number+'</li>');
  125. }
  126. return '</ul><p>FirstKey: '+ firstKey + ' LastKey: '+ prevKey+'</p>';
  127. }),
  128. },
  129. shows: {
  130. "welcome": stringFun(function(doc,req) {
  131. return "Welcome " + req.query["name"];
  132. }),
  133. "welcome2": stringFun(function(doc, req) {
  134. return "Welcome " + doc.name;
  135. }),
  136. "welcome3": stringFun(function(doc,req) {
  137. return "Welcome " + req.query["name"];
  138. })
  139. },
  140. updates: {
  141. "hello" : stringFun(function(doc, req) {
  142. if (!doc) {
  143. if (req.id) {
  144. return [{
  145. _id : req.id
  146. }, "New World"]
  147. }
  148. return [null, "Empty World"];
  149. }
  150. doc.world = "hello";
  151. doc.edited_by = req.userCtx;
  152. return [doc, "hello doc"];
  153. }),
  154. "welcome2": stringFun(function(doc, req) {
  155. if (!doc) {
  156. if (req.id) {
  157. return [{
  158. _id: req.id,
  159. name: req.id
  160. }, "New World"]
  161. }
  162. return [null, "Empty World"];
  163. }
  164. return [doc, "hello doc"];
  165. })
  166. },
  167. views : {
  168. basicView : {
  169. map : stringFun(function(doc) {
  170. if (doc.integer) {
  171. emit(doc.integer, doc.string);
  172. }
  173. })
  174. },
  175. complexView: {
  176. map: stringFun(function(doc) {
  177. if (doc.type == "complex") {
  178. emit([doc.a, doc.b], doc.string);
  179. }
  180. })
  181. },
  182. complexView2: {
  183. map: stringFun(function(doc) {
  184. if (doc.type == "complex") {
  185. emit(doc.a, doc.string);
  186. }
  187. })
  188. },
  189. complexView3: {
  190. map: stringFun(function(doc) {
  191. if (doc.type == "complex") {
  192. emit(doc.b, doc.string);
  193. }
  194. })
  195. }
  196. }
  197. }
  198. db.save(designDoc);
  199. var docs = makeDocs(0, 10);
  200. db.bulkSave(docs);
  201. var docs2 = [
  202. {"a": 1, "b": 1, "string": "doc 1", "type": "complex"},
  203. {"a": 1, "b": 2, "string": "doc 2", "type": "complex"},
  204. {"a": "test", "b": {}, "string": "doc 3", "type": "complex"},
  205. {"a": "test", "b": ["test", "essai"], "string": "doc 4", "type": "complex"},
  206. {"a": {"c": 1}, "b": "", "string": "doc 5", "type": "complex"}
  207. ];
  208. db.bulkSave(docs2);
  209. // test simple rewriting
  210. req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo");
  211. T(req.responseText == "This is a base64 encoded text");
  212. T(req.getResponseHeader("Content-Type") == "text/plain");
  213. req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo2");
  214. T(req.responseText == "This is a base64 encoded text");
  215. T(req.getResponseHeader("Content-Type") == "text/plain");
  216. // test POST
  217. // hello update world
  218. var doc = {"word":"plankton", "name":"Rusty"}
  219. var resp = db.save(doc);
  220. T(resp.ok);
  221. var docid = resp.id;
  222. xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/hello/"+docid);
  223. T(xhr.status == 201);
  224. T(xhr.responseText == "hello doc");
  225. T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")))
  226. doc = db.open(docid);
  227. T(doc.world == "hello");
  228. req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome?name=user");
  229. T(req.responseText == "Welcome user");
  230. req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome/user");
  231. T(req.responseText == "Welcome user");
  232. req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome2");
  233. T(req.responseText == "Welcome user");
  234. xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
  235. T(xhr.status == 201);
  236. T(xhr.responseText == "New World");
  237. T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
  238. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
  239. T(xhr.responseText == "Welcome test");
  240. req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome4/user");
  241. T(req.responseText == "Welcome user");
  242. req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome5/welcome3");
  243. T(req.responseText == "Welcome welcome3");
  244. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/basicView");
  245. T(xhr.status == 200, "view call");
  246. T(/{"total_rows":9/.test(xhr.responseText));
  247. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView");
  248. T(xhr.status == 200, "with query params");
  249. T(/FirstKey: [1, 2]/.test(xhr.responseText));
  250. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView2");
  251. T(xhr.status == 200, "with query params");
  252. T(/Value: doc 3/.test(xhr.responseText));
  253. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView3");
  254. T(xhr.status == 200, "with query params");
  255. T(/Value: doc 4/.test(xhr.responseText));
  256. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView4");
  257. T(xhr.status == 200, "with query params");
  258. T(/Value: doc 5/.test(xhr.responseText));
  259. // COUCHDB-1612 - send body rewriting get to post
  260. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/sendBody1");
  261. T(xhr.status == 200, "get->post rewrite failed:\n"+xhr.responseText);
  262. T(/Value: doc 5 LineNo: 1/.test(xhr.responseText), "get->post rewrite responded wrong:\n"+xhr.responseText);
  263. // COUCHDB-2031 - path normalization versus qs params
  264. xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/db/_design/test?meta=true");
  265. T(xhr.status == 200, "path normalization works with qs params");
  266. var result = JSON.parse(xhr.responseText);
  267. T(result['_id'] == "_design/test");
  268. T(typeof(result['_revs_info']) === "object");
  269. // test early response
  270. var ddoc = {
  271. _id: "_design/response",
  272. rewrites: stringFun(function(req){
  273. status = parseInt(req.query.status);
  274. return {code: status,
  275. body: JSON.stringify({"status": status}),
  276. headers: {'x-foo': 'bar', 'Content-Type': 'application/json'}};
  277. })
  278. }
  279. T(db.save(ddoc).ok);
  280. var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=200");
  281. T(xhr.status == 200);
  282. T(xhr.headers['x-foo'] == 'bar');
  283. T(xhr.responseText == '{"status":200}');
  284. var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=451");
  285. T(xhr.status == 451);
  286. T(xhr.headers['Content-Type'] == 'application/json');
  287. var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=600");
  288. T(xhr.status == 500);
  289. // test path relative to server
  290. var ddoc = {
  291. _id: "_design/relative",
  292. rewrites: stringFun(function(req){
  293. return '../../../_uuids'
  294. })
  295. }
  296. T(db.save(ddoc).ok);
  297. var xhr = CouchDB.request("GET", "/"+dbName+"/_design/relative/_rewrite/uuids");
  298. T(xhr.status == 200);
  299. var result = JSON.parse(xhr.responseText);
  300. T(result.uuids.length == 1);
  301. // test loop
  302. var ddoc_loop = {
  303. _id: "_design/loop",
  304. rewrites: stringFun(function(req) {
  305. return '_rewrite/loop';
  306. })
  307. };
  308. db.save(ddoc_loop);
  309. var url = "/"+dbName+"/_design/loop/_rewrite/loop";
  310. var xhr = CouchDB.request("GET", url);
  311. TEquals(400, xhr.status);
  312. // cleanup
  313. db.deleteDb();
  314. }
  315. }