PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/test/extensions/filter.js

https://github.com/antonyraj/backgrid
JavaScript | 644 lines | 566 code | 71 blank | 7 comment | 1 complexity | 52854f6e6d45ec9cbb3e2bba85751272 MD5 | raw file
Possible License(s): MIT
  1. /*
  2. backgrid
  3. http://github.com/wyuenho/backgrid
  4. Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
  5. Licensed under the MIT @license.
  6. */
  7. describe("A ServerSideFilter", function () {
  8. var ajax, collection;
  9. beforeEach(function () {
  10. collection = new (Backbone.Collection.extend({
  11. url: "http://www.example.com"
  12. }))([{id: 1}, {id: 2}]);
  13. ajax = $.ajax;
  14. });
  15. afterEach(function () {
  16. $.ajax = ajax;
  17. });
  18. it("can render a search box with and optional name and a placeholder", function () {
  19. var filter = new Backgrid.Extension.ServerSideFilter({
  20. collection: collection,
  21. name: "name",
  22. placeholder: "placeholder"
  23. });
  24. filter.render();
  25. expect(filter.searchBox().attr("name")).toBe("name");
  26. expect(filter.searchBox().attr("placeholder")).toBe("placeholder");
  27. var filter = new Backgrid.Extension.ServerSideFilter({
  28. collection: collection,
  29. name: "name"
  30. });
  31. filter.render();
  32. expect(filter.searchBox().attr("placeholder")).toBeUndefined();
  33. expect(filter.searchBox().attr("name")).toBe("name");
  34. var filter = new Backgrid.Extension.ServerSideFilter({
  35. collection: collection,
  36. placeholder: "placeholder"
  37. });
  38. filter.render();
  39. expect(filter.searchBox().attr("placeholder")).toBe("placeholder");
  40. var filter = new Backgrid.Extension.ServerSideFilter({
  41. collection: collection
  42. });
  43. filter.render();
  44. expect(filter.searchBox().attr("placeholder")).toBeUndefined();
  45. });
  46. it("can fetch with a query on submit", function () {
  47. var url, data;
  48. $.ajax = function (settings) {
  49. url = settings.url;
  50. data = settings.data;
  51. settings.success([{id: 1}]);
  52. };
  53. var filter = new Backgrid.Extension.ServerSideFilter({
  54. collection: collection
  55. });
  56. filter.render();
  57. filter.searchBox().val("query");
  58. filter.$el.submit();
  59. expect(url).toBe("http://www.example.com");
  60. expect(data).toEqual({q: "query"});
  61. expect(collection.length).toBe(1);
  62. expect(collection.at(0).toJSON()).toEqual({id: 1});
  63. filter = new Backgrid.Extension.ServerSideFilter({
  64. collection: new Backbone.PageableCollection(null, {
  65. url: "http://www.example.com"
  66. })
  67. });
  68. filter.render();
  69. filter.searchBox().val("query");
  70. filter.$el.submit();
  71. expect(url).toBe("http://www.example.com");
  72. expect(data).toEqual({q: "query", page: 1, "per_page": 25});
  73. expect(collection.length).toBe(1);
  74. expect(collection.at(0).toJSON()).toEqual({id: 1});
  75. });
  76. it("fetches without the query parameter if the search box is empty", function () {
  77. var url, data;
  78. $.ajax = function (settings) {
  79. url = settings.url;
  80. data = settings.data;
  81. settings.success([{id: 1}]);
  82. };
  83. var filter = new Backgrid.Extension.ServerSideFilter({
  84. collection: collection
  85. });
  86. filter.render();
  87. filter.searchBox().val("");
  88. filter.$el.submit();
  89. expect(url).toBe("http://www.example.com");
  90. expect(data).toEqual({});
  91. expect(collection.length).toBe(1);
  92. expect(collection.at(0).toJSON()).toEqual({id: 1});
  93. var filter = new Backgrid.Extension.ServerSideFilter({
  94. collection: new Backbone.PageableCollection(null, {
  95. url: "http://www.example.com"
  96. })
  97. });
  98. filter.render();
  99. filter.searchBox().val("");
  100. filter.$el.submit();
  101. expect(url).toBe("http://www.example.com");
  102. expect(data).toEqual({page: 1, "per_page": 25});
  103. expect(collection.length).toBe(1);
  104. expect(collection.at(0).toJSON()).toEqual({id: 1});
  105. });
  106. it("can persist the filter parameter on pagination", function () {
  107. var url, data;
  108. $.ajax = function (settings) {
  109. url = settings.url;
  110. data = settings.data;
  111. settings.success([{id: 2}]);
  112. };
  113. collection = new Backbone.PageableCollection([{id: 1}], {
  114. url: "http://www.example.com",
  115. state: {
  116. pageSize: 1,
  117. totalRecords: 3
  118. },
  119. queryParams: {
  120. totalRecords: null,
  121. totalPages: null
  122. }
  123. });
  124. var filter = new Backgrid.Extension.ServerSideFilter({
  125. collection: collection
  126. });
  127. filter.render();
  128. filter.searchBox().val("query");
  129. collection.getPage(2);
  130. expect(filter.searchBox().val()).toBe("query");
  131. expect(url).toBe("http://www.example.com");
  132. expect(data).toEqual({q: "query", page: 2, "per_page": 1});
  133. expect(collection.length).toBe(1);
  134. expect(collection.at(0).toJSON()).toEqual({id: 2});
  135. });
  136. it("goes back to the first page when the query changes", function () {
  137. var url, data;
  138. $.ajax = function (settings) {
  139. url = settings.url;
  140. data = settings.data;
  141. settings.success([{id: 3}]);
  142. };
  143. collection = new Backbone.PageableCollection([{id: 1}, {id: 2}], {
  144. url: "http://www.example.com",
  145. state: {
  146. pageSize: 1,
  147. totalRecords: 3
  148. },
  149. queryParams: {
  150. totalRecords: null,
  151. totalPages: null
  152. }
  153. });
  154. var filter = new Backgrid.Extension.ServerSideFilter({
  155. collection: collection
  156. });
  157. filter.render();
  158. collection.getPage(2);
  159. filter.searchBox().val("query");
  160. filter.$el.submit();
  161. expect(url).toBe("http://www.example.com");
  162. expect(data).toEqual({q: "query", page: 1, "per_page": 1});
  163. expect(collection.length).toBe(1);
  164. expect(collection.state.currentPage).toBe(1);
  165. expect(collection.state.totalRecords).toBe(3);
  166. expect(collection.at(0).toJSON()).toEqual({id: 3});
  167. });
  168. it("can clear the search box and refetch upon clicking the cross", function () {
  169. spyOn(collection, "fetch");
  170. var filter = new Backgrid.Extension.ServerSideFilter({
  171. collection: collection
  172. });
  173. filter.render();
  174. filter.searchBox().val("query");
  175. filter.$el.find(".close").click();
  176. expect(filter.searchBox().val()).toBe("");
  177. collection.fetch.reset();
  178. });
  179. });
  180. describe("A ClientSideFilter", function () {
  181. var collection;
  182. beforeEach(function () {
  183. collection = new (Backbone.Collection.extend({
  184. url: "http://www.example.com"
  185. }))([{id: 1, name: "alice"},
  186. {id: 2, name: "alicia"},
  187. {id: 3, name: "bob"}]);
  188. });
  189. it("can perform a regex search on keydown and submit, and cancel on clicking the close button", function () {
  190. var filter;
  191. runs(function () {
  192. filter = new Backgrid.Extension.ClientSideFilter({
  193. collection: collection,
  194. fields: ["name"]
  195. });
  196. filter.render();
  197. expect(collection.length).toBe(3);
  198. expect(collection.at(0).id).toBe(1);
  199. expect(collection.at(1).id).toBe(2);
  200. expect(collection.at(2).id).toBe(3);
  201. });
  202. runs(function () {
  203. filter.searchBox().val("bob").keydown();
  204. });
  205. waitsFor(function () {
  206. return collection.length === 1;
  207. }, "collection.length to become 1", 500);
  208. runs(function () {
  209. expect(collection.at(0).id).toBe(3);
  210. });
  211. runs(function () {
  212. filter.$el.find(".close").click();
  213. });
  214. waitsFor(function () {
  215. return collection.length === 3;
  216. }, "collection.length to become 3", 500);
  217. runs(function () {
  218. expect(collection.at(0).id).toBe(1);
  219. expect(collection.at(1).id).toBe(2);
  220. expect(collection.at(2).id).toBe(3);
  221. });
  222. runs(function () {
  223. filter.searchBox().val("ALICE");
  224. filter.$el.submit();
  225. });
  226. waitsFor(function () {
  227. return collection.length === 1;
  228. }, "collection.length to become 1", 500);
  229. runs(function () {
  230. expect(collection.at(0).id).toBe(1);
  231. });
  232. runs(function () {
  233. filter.searchBox().val("al").keydown();
  234. });
  235. waitsFor(function () {
  236. return collection.length === 2;
  237. }, "collection.length to become 2", 500);
  238. runs(function () {
  239. expect(collection.at(0).id).toBe(1);
  240. expect(collection.at(1).id).toBe(2);
  241. });
  242. runs(function () {
  243. filter.searchBox().val("alic bob").keydown();
  244. });
  245. waitsFor(function () {
  246. return collection.length === 3;
  247. }, "collection.length to become 3", 500);
  248. runs(function () {
  249. expect(collection.at(0).id).toBe(1);
  250. expect(collection.at(1).id).toBe(2);
  251. expect(collection.at(2).id).toBe(3);
  252. });
  253. });
  254. it("will reflect in the search result when a new model is added to the collection", function () {
  255. var filter;
  256. runs(function () {
  257. filter = new Backgrid.Extension.ClientSideFilter({
  258. collection: collection,
  259. fields: ["name"]
  260. });
  261. filter.render();
  262. collection.add({id: 4, name: "doug"});
  263. filter.searchBox().val("doug").keydown();
  264. });
  265. waitsFor(function () {
  266. return collection.length === 1;
  267. }, "collection.length to become 1", 500);
  268. runs(function () {
  269. expect(collection.at(0).id).toBe(4);
  270. });
  271. });
  272. it("will reflect in the search result when a model is removed from the collection", function () {
  273. var filter;
  274. runs(function () {
  275. filter = new Backgrid.Extension.ClientSideFilter({
  276. collection: collection,
  277. fields: ["name"]
  278. });
  279. filter.render();
  280. collection.remove(collection.at(0));
  281. filter.searchBox().val("alice").keydown();
  282. });
  283. waitsFor(function () {
  284. return collection.length === 0;
  285. }, "collection.length to become 0", 500);
  286. runs(function () {
  287. expect(filter.shadowCollection.length).toBe(2);
  288. expect(filter.shadowCollection.at(0).id).toBe(2);
  289. expect(filter.shadowCollection.at(1).id).toBe(3);
  290. });
  291. });
  292. it("will reflect in the search result when a model attribute is changed", function () {
  293. var filter;
  294. runs(function () {
  295. filter = new Backgrid.Extension.ClientSideFilter({
  296. collection: collection,
  297. fields: ["name"]
  298. });
  299. filter.render();
  300. filter.collection.at(0).set("name", "charlie");
  301. filter.searchBox().val("charlie").keydown();
  302. });
  303. waitsFor(function () {
  304. return collection.length === 1;
  305. }, "collection.length to become 1", 500);
  306. runs(function () {
  307. expect(filter.shadowCollection.at(0).id).toBe(1);
  308. expect(filter.shadowCollection.at(0).get("name")).toBe("charlie");
  309. expect(filter.collection.at(0).get("name")).toBe("charlie");
  310. });
  311. });
  312. it("will reflect in the search result when the collection is reset", function () {
  313. var filter;
  314. runs(function () {
  315. filter = new Backgrid.Extension.ClientSideFilter({
  316. collection: collection,
  317. fields: ["name"]
  318. });
  319. filter.render();
  320. filter.collection.reset([{id: 4, name: "charlie"}, {id: 5, name: "doug"}]);
  321. filter.searchBox().val("").keydown();
  322. });
  323. waitsFor(function () {
  324. return collection.length === 2;
  325. }, "collection.length to become 2", 500);
  326. runs(function () {
  327. expect(filter.shadowCollection.at(0).id).toBe(4);
  328. expect(filter.shadowCollection.at(1).id).toBe(5);
  329. expect(filter.shadowCollection.at(0).get("name")).toBe("charlie");
  330. expect(filter.shadowCollection.at(1).get("name")).toBe("doug");
  331. expect(filter.collection.at(0).id).toBe(4);
  332. expect(filter.collection.at(1).id).toBe(5);
  333. expect(filter.collection.at(0).get("name")).toBe("charlie");
  334. expect(filter.collection.at(1).get("name")).toBe("doug");
  335. });
  336. });
  337. it("goes back to the first page when the query changes", function () {
  338. var filter;
  339. runs(function () {
  340. collection = new Backbone.PageableCollection([
  341. {id: 1, name: "alice"},
  342. {id: 2, name: "bob"}], {
  343. state: {
  344. pageSize: 1,
  345. },
  346. mode: "client"
  347. });
  348. filter = new Backgrid.Extension.ClientSideFilter({
  349. collection: collection,
  350. fields: ["name"]
  351. });
  352. filter.render();
  353. collection.getPage(2);
  354. filter.searchBox().val("bob").keydown();
  355. });
  356. waitsFor(function () {
  357. return collection.state.currentPage === 1;
  358. }, "collection.state.currentPage to become 1", 500);
  359. runs(function () {
  360. expect(collection.length).toBe(1);
  361. expect(filter.shadowCollection.at(0).id).toBe(1);
  362. expect(filter.shadowCollection.at(1).id).toBe(2);
  363. expect(filter.shadowCollection.at(0).get("name")).toBe("alice");
  364. expect(filter.shadowCollection.at(1).get("name")).toBe("bob");
  365. expect(collection.state.currentPage).toBe(1);
  366. expect(collection.state.totalRecords).toBe(1);
  367. expect(collection.at(0).toJSON()).toEqual({id: 2, name: "bob"});
  368. });
  369. });
  370. });
  371. describe("A LunrFilter", function () {
  372. var collection;
  373. beforeEach(function () {
  374. collection = new (Backbone.Collection.extend({
  375. url: "http://www.example.com"
  376. }))([{id: 1, name: "alice", bio: "a fat cat sat on a mat and ate a fat rat"},
  377. {id: 2, name: "bob", bio: "he is fat but does not crap"}]);
  378. });
  379. it("can perform a full-text search on keydown and submit, and cancel on clicking the close button", function () {
  380. var filter;
  381. runs(function () {
  382. filter = new Backgrid.Extension.LunrFilter({
  383. collection: collection,
  384. fields: {name: 1, bio: 10}
  385. });
  386. filter.render();
  387. expect(collection.length).toBe(2);
  388. expect(collection.at(0).id).toBe(1);
  389. expect(collection.at(1).id).toBe(2);
  390. });
  391. runs(function () {
  392. filter.searchBox().val("crap").keydown();
  393. });
  394. waitsFor(function () {
  395. return collection.length === 1;
  396. }, "collection.length to become 1", 500);
  397. runs(function () {
  398. expect(collection.at(0).id).toBe(2);
  399. });
  400. runs(function () {
  401. filter.$el.find(".close").click();
  402. });
  403. waitsFor(function () {
  404. return collection.length === 2;
  405. }, "collection.length to become 2", 500);
  406. runs(function () {
  407. expect(collection.at(0).id).toBe(1);
  408. expect(collection.at(1).id).toBe(2);
  409. });
  410. runs(function () {
  411. filter.searchBox().val("alice");
  412. filter.$el.submit();
  413. });
  414. waitsFor(function () {
  415. return collection.length === 1;
  416. }, "collection.length to become 1", 500);
  417. runs(function () {
  418. expect(collection.at(0).id).toBe(1);
  419. });
  420. runs(function () {
  421. filter.searchBox().val("fat").keydown();
  422. });
  423. waitsFor(function () {
  424. return collection.length === 2;
  425. }, "collection.length to become 2", 500);
  426. runs(function () {
  427. expect(collection.at(0).id).toBe(2);
  428. expect(collection.at(1).id).toBe(1);
  429. });
  430. });
  431. it("will reindex on reset", function () {
  432. var filter = new Backgrid.Extension.LunrFilter({
  433. collection: collection,
  434. fields: {name: 1, bio: 10}
  435. });
  436. runs(function () {
  437. filter = new Backgrid.Extension.LunrFilter({
  438. collection: collection,
  439. fields: {name: 1, bio: 10}
  440. });
  441. filter.render();
  442. collection.reset([{id: 3, name: "charlie", bio: "The cat scared the bat and sat on the mat."},
  443. {id: 4, name: "doug", bio: "The snail hid in his shell. It heard a bell. He went to see it was the church bell."}]);
  444. });
  445. runs(function () {
  446. filter.searchBox().val("crap").keydown();
  447. });
  448. waitsFor(function () {
  449. return collection.length === 0;
  450. }, "collection.length to become 0", 500);
  451. runs(function () {
  452. filter.searchBox().val("alice").keydown();
  453. });
  454. waitsFor(function () {
  455. return collection.length === 0;
  456. }, "collection.length to become 0", 500);
  457. runs(function () {
  458. filter.searchBox().val("charlie").keydown();
  459. });
  460. waitsFor(function () {
  461. return collection.length === 1;
  462. }, "collection.length to become 1", 500);
  463. runs(function () {
  464. expect(collection.at(0).id).toBe(3);
  465. });
  466. runs(function () {
  467. filter.searchBox().val("doug").keydown();
  468. });
  469. waitsFor(function () {
  470. return collection.length === 1 && collection.at(0).id === 4;
  471. }, "colleciton.length to become 1 and collection.at(0).id to become 4", 500);
  472. });
  473. it("will update the index on add", function () {
  474. var filter;
  475. runs(function () {
  476. filter = new Backgrid.Extension.LunrFilter({
  477. collection: collection,
  478. fields: {name: 1, bio: 10}
  479. });
  480. filter.render();
  481. collection.add({id: 3, name: "charlie", bio: "The cat scared the bat and sat on the mat."});
  482. });
  483. runs(function () {
  484. filter.searchBox().val("charlie").keydown();
  485. });
  486. waitsFor(function () {
  487. return collection.length === 1;
  488. }, "collection.length to become 0", 500);
  489. runs(function () {
  490. expect(collection.at(0).id).toBe(3);
  491. });
  492. });
  493. it("will update the index on remove", function () {
  494. var filter;
  495. runs(function () {
  496. filter = new Backgrid.Extension.LunrFilter({
  497. collection: collection,
  498. fields: {name: 1, bio: 10}
  499. });
  500. filter.render();
  501. collection.remove(collection.last());
  502. });
  503. runs(function () {
  504. filter.searchBox().val("bob").keydown();
  505. });
  506. waitsFor(function () {
  507. return collection.length === 0;
  508. }, "collection.length to become 0", 500);
  509. runs(function () {
  510. filter.searchBox().val("alice").keydown();
  511. });
  512. waitsFor(function () {
  513. return collection.length === 1;
  514. });
  515. runs(function () {
  516. expect(collection.at(0).id).toBe(1);
  517. });
  518. });
  519. it("will update the index on change", function () {
  520. var filter;
  521. runs(function () {
  522. filter = new Backgrid.Extension.LunrFilter({
  523. collection: collection,
  524. fields: {name: 1, bio: 10}
  525. });
  526. filter.render();
  527. collection.at(0).set("name", "charlie");
  528. });
  529. runs(function () {
  530. filter.searchBox().val("alice").keydown();
  531. });
  532. waitsFor(function () {
  533. return collection.length === 0;
  534. }, "collection.length to become 0", 500);
  535. runs(function () {
  536. filter.searchBox().val("charlie").keydown();
  537. });
  538. waitsFor(function () {
  539. return collection.length === 1;
  540. }, "collection.length to become 1", 500);
  541. runs(function () {
  542. expect(collection.at(0).id).toBe(1);
  543. });
  544. });
  545. it("can clear the search box and reindex upon clicking the close button", function () {
  546. var filter;
  547. runs(function () {
  548. filter = new Backgrid.Extension.LunrFilter({
  549. collection: collection,
  550. fields: {name: 1, bio: 10}
  551. });
  552. filter.render();
  553. });
  554. runs(function() {
  555. filter.searchBox().val("crap").keydown();
  556. });
  557. waitsFor(function () {
  558. return collection.length === 1;
  559. }, "collection.length to become 1", 500);
  560. runs(function () {
  561. filter.$el.find(".close").click();
  562. });
  563. waitsFor(function () {
  564. return collection.length === 2;
  565. }, "collection.length to become 2", 500);
  566. runs(function () {
  567. expect(filter.searchBox().val()).toBe('');
  568. expect(collection.at(0).id).toBe(1);
  569. expect(collection.at(1).id).toBe(2);
  570. });
  571. });
  572. });