router.core.spec.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. Router = FlowRouter.Router;
  2. Tinytest.addAsync('Client - Router - define and go to route', function (test, next) {
  3. var rand = Random.id();
  4. var rendered = 0;
  5. FlowRouter.route('/' + rand, {
  6. action: function(_params) {
  7. rendered++;
  8. }
  9. });
  10. FlowRouter.go('/' + rand);
  11. setTimeout(function() {
  12. test.equal(rendered, 1);
  13. setTimeout(next, 100);
  14. }, 100);
  15. });
  16. Tinytest.addAsync('Client - Router - define and go to route with fields',
  17. function (test, next) {
  18. var rand = Random.id();
  19. var pathDef = "/" + rand + "/:key";
  20. var rendered = 0;
  21. FlowRouter.route(pathDef, {
  22. action: function(params) {
  23. test.equal(params.key, "abc +@%");
  24. rendered++;
  25. }
  26. });
  27. FlowRouter.go(pathDef, {key: "abc +@%"});
  28. setTimeout(function() {
  29. test.equal(rendered, 1);
  30. setTimeout(next, 100);
  31. }, 100);
  32. });
  33. Tinytest.addAsync('Client - Router - parse params and query', function (test, next) {
  34. var rand = Random.id();
  35. var rendered = 0;
  36. var params = null;
  37. FlowRouter.route('/' + rand + '/:foo', {
  38. action: function(_params) {
  39. rendered++;
  40. params = _params;
  41. }
  42. });
  43. FlowRouter.go('/' + rand + '/bar');
  44. setTimeout(function() {
  45. test.equal(rendered, 1);
  46. test.equal(params.foo, 'bar');
  47. setTimeout(next, 100);
  48. }, 100);
  49. });
  50. Tinytest.addAsync('Client - Router - redirect using FlowRouter.go', function (test, next) {
  51. var rand = Random.id(), rand2 = Random.id();
  52. var log = [];
  53. var paths = ['/' + rand2, '/' + rand];
  54. var done = false;
  55. FlowRouter.route(paths[0], {
  56. action: function(_params) {
  57. log.push(1);
  58. FlowRouter.go(paths[1]);
  59. }
  60. });
  61. FlowRouter.route(paths[1], {
  62. action: function(_params) {
  63. log.push(2);
  64. }
  65. });
  66. FlowRouter.go(paths[0]);
  67. setTimeout(function() {
  68. test.equal(log, [1, 2]);
  69. done = true;
  70. next();
  71. }, 100);
  72. });
  73. Tinytest.addAsync('Client - Router - get current route path', function (test, next) {
  74. var value = Random.id();
  75. var randomValue = Random.id();
  76. var pathDef = "/" + randomValue + '/:_id';
  77. var path = "/" + randomValue + "/" + value;
  78. var detectedValue = null;
  79. FlowRouter.route(pathDef, {
  80. action: function(params) {
  81. detectedValue = params._id;
  82. }
  83. });
  84. FlowRouter.go(path);
  85. Meteor.setTimeout(function() {
  86. test.equal(detectedValue, value);
  87. test.equal(FlowRouter.current().path, path);
  88. next();
  89. }, 50);
  90. });
  91. Tinytest.addAsync('Client - Router - subscribe to global subs', function (test, next) {
  92. var rand = Random.id();
  93. FlowRouter.route('/' + rand);
  94. FlowRouter.subscriptions = function (path) {
  95. test.equal(path, '/' + rand);
  96. this.register('baz', Meteor.subscribe('baz'));
  97. };
  98. FlowRouter.go('/' + rand);
  99. setTimeout(function() {
  100. test.isTrue(!!GetSub('baz'));
  101. FlowRouter.subscriptions = Function.prototype;
  102. next();
  103. }, 100);
  104. });
  105. Tinytest.addAsync('Client - Router - setParams - generic', function (test, done) {
  106. var randomKey = Random.id();
  107. var pathDef = "/" + randomKey + "/:cat/:id";
  108. var paramsList = [];
  109. FlowRouter.route(pathDef, {
  110. action: function(params) {
  111. paramsList.push(params);
  112. }
  113. });
  114. FlowRouter.go(pathDef, {cat: "meteor", id: "200"});
  115. setTimeout(function() {
  116. // return done();
  117. var success = FlowRouter.setParams({id: "700"});
  118. test.isTrue(success);
  119. setTimeout(validate, 50);
  120. }, 50);
  121. function validate() {
  122. test.equal(paramsList.length, 2);
  123. test.equal(_.pick(paramsList[0], "id", "cat"), {cat: "meteor", id: "200"});
  124. test.equal(_.pick(paramsList[1], "id", "cat"), {cat: "meteor", id: "700"});
  125. done();
  126. }
  127. });
  128. Tinytest.addAsync('Client - Router - setParams - preserve query strings', function (test, done) {
  129. var randomKey = Random.id();
  130. var pathDef = "/" + randomKey + "/:cat/:id";
  131. var paramsList = [];
  132. var queryParamsList = [];
  133. FlowRouter.route(pathDef, {
  134. action: function(params, queryParams) {
  135. paramsList.push(params);
  136. queryParamsList.push(queryParams);
  137. }
  138. });
  139. FlowRouter.go(pathDef, {cat: "meteor", id: "200 +% / ad"}, {aa: "20 +%"});
  140. setTimeout(function() {
  141. // return done();
  142. var success = FlowRouter.setParams({id: "700 +% / ad"});
  143. test.isTrue(success);
  144. setTimeout(validate, 50);
  145. }, 50);
  146. function validate() {
  147. test.equal(paramsList.length, 2);
  148. test.equal(queryParamsList.length, 2);
  149. test.equal(_.pick(paramsList[0], "id", "cat"), {cat: "meteor", id: "200 +% / ad"});
  150. test.equal(_.pick(paramsList[1], "id", "cat"), {cat: "meteor", id: "700 +% / ad"});
  151. test.equal(queryParamsList, [{aa: "20 +%"}, {aa: "20 +%"}]);
  152. done();
  153. }
  154. });
  155. Tinytest.add('Client - Router - setParams - no route selected', function (test) {
  156. var originalRoute = FlowRouter._current.route;
  157. FlowRouter._current.route = undefined;
  158. var success = FlowRouter.setParams({id: "800"});
  159. test.isFalse(success);
  160. FlowRouter._current.route = originalRoute;
  161. });
  162. Tinytest.addAsync('Client - Router - setQueryParams - using check', function (test, done) {
  163. var randomKey = Random.id();
  164. var pathDef = "/" + randomKey + "";
  165. var queryParamsList = [];
  166. FlowRouter.route(pathDef, {
  167. action: function(params, queryParams) {
  168. queryParamsList.push(queryParams);
  169. }
  170. });
  171. FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
  172. setTimeout(function() {
  173. check(FlowRouter.current().queryParams, {cat: String, id: String});
  174. done();
  175. }, 50);
  176. });
  177. Tinytest.addAsync('Client - Router - setQueryParams - generic', function (test, done) {
  178. var randomKey = Random.id();
  179. var pathDef = "/" + randomKey + "";
  180. var queryParamsList = [];
  181. FlowRouter.route(pathDef, {
  182. action: function(params, queryParams) {
  183. queryParamsList.push(queryParams);
  184. }
  185. });
  186. FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
  187. setTimeout(function() {
  188. // return done();
  189. var success = FlowRouter.setQueryParams({id: "700"});
  190. test.isTrue(success);
  191. setTimeout(validate, 50);
  192. }, 50);
  193. function validate() {
  194. test.equal(queryParamsList.length, 2);
  195. test.equal(_.pick(queryParamsList[0], "id", "cat"), {cat: "meteor", id: "200"});
  196. test.equal(_.pick(queryParamsList[1], "id", "cat"), {cat: "meteor", id: "700"});
  197. done();
  198. }
  199. });
  200. Tinytest.addAsync('Client - Router - setQueryParams - remove query param null', function (test, done) {
  201. var randomKey = Random.id();
  202. var pathDef = "/" + randomKey + "";
  203. var queryParamsList = [];
  204. FlowRouter.route(pathDef, {
  205. action: function(params, queryParams) {
  206. queryParamsList.push(queryParams);
  207. }
  208. });
  209. FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
  210. setTimeout(function() {
  211. var success = FlowRouter.setQueryParams({id: "700", cat: null});
  212. test.isTrue(success);
  213. setTimeout(validate, 50);
  214. }, 50);
  215. function validate() {
  216. test.equal(queryParamsList.length, 2);
  217. test.equal(_.pick(queryParamsList[0], "id", "cat"), {cat: "meteor", id: "200"});
  218. test.equal(queryParamsList[1], {id: "700"});
  219. done();
  220. }
  221. });
  222. Tinytest.addAsync('Client - Router - setQueryParams - remove query param undefined', function (test, done) {
  223. var randomKey = Random.id();
  224. var pathDef = "/" + randomKey + "";
  225. var queryParamsList = [];
  226. FlowRouter.route(pathDef, {
  227. action: function(params, queryParams) {
  228. queryParamsList.push(queryParams);
  229. }
  230. });
  231. FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
  232. setTimeout(function() {
  233. var success = FlowRouter.setQueryParams({id: "700", cat: undefined});
  234. test.isTrue(success);
  235. setTimeout(validate, 50);
  236. }, 50);
  237. function validate() {
  238. test.equal(queryParamsList.length, 2);
  239. test.equal(_.pick(queryParamsList[0], "id", "cat"), {cat: "meteor", id: "200"});
  240. test.equal(queryParamsList[1], {id: "700"});
  241. done();
  242. }
  243. });
  244. Tinytest.addAsync('Client - Router - setQueryParams - preserve params', function (test, done) {
  245. var randomKey = Random.id();
  246. var pathDef = "/" + randomKey + "/:abc";
  247. var queryParamsList = [];
  248. var paramsList = [];
  249. FlowRouter.route(pathDef, {
  250. action: function(params, queryParams) {
  251. paramsList.push(params);
  252. queryParamsList.push(queryParams);
  253. }
  254. });
  255. FlowRouter.go(pathDef, {abc: "20"}, {cat: "meteor", id: "200"});
  256. setTimeout(function() {
  257. // return done();
  258. var success = FlowRouter.setQueryParams({id: "700"});
  259. test.isTrue(success);
  260. setTimeout(validate, 50);
  261. }, 50);
  262. function validate() {
  263. test.equal(queryParamsList.length, 2);
  264. test.equal(queryParamsList, [
  265. {cat: "meteor", id: "200"}, {cat: "meteor", id: "700"}
  266. ]);
  267. test.equal(paramsList.length, 2);
  268. test.equal(_.pick(paramsList[0], "abc"), {abc: "20"});
  269. test.equal(_.pick(paramsList[1], "abc"), {abc: "20"});
  270. done();
  271. }
  272. });
  273. Tinytest.add('Client - Router - setQueryParams - no route selected', function (test) {
  274. var originalRoute = FlowRouter._current.route;
  275. FlowRouter._current.route = undefined;
  276. var success = FlowRouter.setQueryParams({id: "800"});
  277. test.isFalse(success);
  278. FlowRouter._current.route = originalRoute;
  279. });
  280. Tinytest.addAsync('Client - Router - notFound', function (test, done) {
  281. var data = [];
  282. FlowRouter.notFound = {
  283. subscriptions: function() {
  284. data.push("subscriptions");
  285. },
  286. action: function() {
  287. data.push("action");
  288. }
  289. };
  290. FlowRouter.go("/" + Random.id());
  291. setTimeout(function() {
  292. test.equal(data, ["subscriptions", "action"]);
  293. done();
  294. }, 50);
  295. });
  296. Tinytest.addAsync('Client - Router - withReplaceState - enabled',
  297. function (test, done) {
  298. var pathDef = "/" + Random.id() + "/:id";
  299. var originalRedirect = FlowRouter._page.replace;
  300. var callCount = 0;
  301. FlowRouter._page.replace = function(path) {
  302. callCount++;
  303. originalRedirect.call(FlowRouter._page, path);
  304. };
  305. FlowRouter.route(pathDef, {
  306. name: name,
  307. action: function(params) {
  308. test.equal(params.id, "awesome");
  309. test.equal(callCount, 1);
  310. FlowRouter._page.replace = originalRedirect;
  311. // We don't use Meteor.defer here since it carries
  312. // Meteor.Environment vars too
  313. // Which breaks our test below
  314. setTimeout(done, 0);
  315. }
  316. });
  317. FlowRouter.withReplaceState(function() {
  318. FlowRouter.go(pathDef, {id: "awesome"});
  319. });
  320. });
  321. Tinytest.addAsync('Client - Router - withReplaceState - disabled',
  322. function (test, done) {
  323. var pathDef = "/" + Random.id() + "/:id";
  324. var originalRedirect = FlowRouter._page.replace;
  325. var callCount = 0;
  326. FlowRouter._page.replace = function(path) {
  327. callCount++;
  328. originalRedirect.call(FlowRouter._page, path);
  329. };
  330. FlowRouter.route(pathDef, {
  331. name: name,
  332. action: function(params) {
  333. test.equal(params.id, "awesome");
  334. test.equal(callCount, 0);
  335. FlowRouter._page.replace = originalRedirect;
  336. Meteor.defer(done);
  337. }
  338. });
  339. FlowRouter.go(pathDef, {id: "awesome"});
  340. });
  341. Tinytest.addAsync('Client - Router - withTrailingSlash - enabled', function (test, next) {
  342. var rand = Random.id();
  343. var rendered = 0;
  344. FlowRouter.route('/' + rand, {
  345. action: function(_params) {
  346. rendered++;
  347. }
  348. });
  349. FlowRouter.withTrailingSlash(function() {
  350. FlowRouter.go('/' + rand);
  351. });
  352. setTimeout(function() {
  353. test.equal(rendered, 1);
  354. test.equal(_.last(location.href), '/');
  355. setTimeout(next, 100);
  356. }, 100);
  357. });
  358. Tinytest.addAsync('Client - Router - idempotent routing - action',
  359. function (test, done) {
  360. var rand = Random.id();
  361. var pathDef = "/" + rand;
  362. var rendered = 0;
  363. FlowRouter.route(pathDef, {
  364. action: function(params) {
  365. rendered++;
  366. }
  367. });
  368. FlowRouter.go(pathDef);
  369. Meteor.defer(function() {
  370. FlowRouter.go(pathDef);
  371. Meteor.defer(function() {
  372. test.equal(rendered, 1);
  373. done();
  374. });
  375. });
  376. });
  377. Tinytest.addAsync('Client - Router - idempotent routing - triggers',
  378. function (test, next) {
  379. var rand = Random.id();
  380. var pathDef = "/" + rand;
  381. var runnedTriggers = 0;
  382. var done = false;
  383. var triggerFns = [function(params) {
  384. if (done) return;
  385. runnedTriggers++;
  386. }];
  387. FlowRouter.triggers.enter(triggerFns);
  388. FlowRouter.route(pathDef, {
  389. triggersEnter: triggerFns,
  390. triggersExit: triggerFns
  391. });
  392. FlowRouter.go(pathDef);
  393. FlowRouter.triggers.exit(triggerFns);
  394. Meteor.defer(function() {
  395. FlowRouter.go(pathDef);
  396. Meteor.defer(function() {
  397. test.equal(runnedTriggers, 2);
  398. done = true;
  399. next();
  400. });
  401. });
  402. });
  403. Tinytest.addAsync('Client - Router - reload - action',
  404. function (test, done) {
  405. var rand = Random.id();
  406. var pathDef = "/" + rand;
  407. var rendered = 0;
  408. FlowRouter.route(pathDef, {
  409. action: function(params) {
  410. rendered++;
  411. }
  412. });
  413. FlowRouter.go(pathDef);
  414. Meteor.defer(function() {
  415. FlowRouter.reload();
  416. Meteor.defer(function() {
  417. test.equal(rendered, 2);
  418. done();
  419. });
  420. });
  421. });
  422. Tinytest.addAsync('Client - Router - reload - triggers',
  423. function (test, next) {
  424. var rand = Random.id();
  425. var pathDef = "/" + rand;
  426. var runnedTriggers = 0;
  427. var done = false;
  428. var triggerFns = [function(params) {
  429. if (done) return;
  430. runnedTriggers++;
  431. }];
  432. FlowRouter.triggers.enter(triggerFns);
  433. FlowRouter.route(pathDef, {
  434. triggersEnter: triggerFns,
  435. triggersExit: triggerFns
  436. });
  437. FlowRouter.go(pathDef);
  438. FlowRouter.triggers.exit(triggerFns);
  439. Meteor.defer(function() {
  440. FlowRouter.reload();
  441. Meteor.defer(function() {
  442. test.equal(runnedTriggers, 6);
  443. done = true;
  444. next();
  445. });
  446. });
  447. });
  448. Tinytest.addAsync(
  449. 'Client - Router - wait - before initialize',
  450. function(test, done) {
  451. FlowRouter._initialized = false;
  452. FlowRouter.wait();
  453. test.equal(FlowRouter._askedToWait, true);
  454. FlowRouter._initialized = true;
  455. FlowRouter._askedToWait = false;
  456. done();
  457. });
  458. Tinytest.addAsync(
  459. 'Client - Router - wait - after initialized',
  460. function(test, done) {
  461. try {
  462. FlowRouter.wait();
  463. } catch(ex) {
  464. test.isTrue(/can't wait/.test(ex.message));
  465. done();
  466. }
  467. });
  468. Tinytest.addAsync(
  469. 'Client - Router - initialize - after initialized',
  470. function(test, done) {
  471. try {
  472. FlowRouter.initialize();
  473. } catch(ex) {
  474. test.isTrue(/already initialized/.test(ex.message));
  475. done();
  476. }
  477. });
  478. Tinytest.addAsync(
  479. 'Client - Router - base path - url updated',
  480. function(test, done) {
  481. var simulatedBasePath = '/flow';
  482. var rand = Random.id();
  483. FlowRouter.route('/' + rand, { action: function() {} });
  484. setBasePath(simulatedBasePath);
  485. FlowRouter.go('/' + rand);
  486. setTimeout(function() {
  487. test.equal(location.pathname, simulatedBasePath + '/' + rand);
  488. resetBasePath();
  489. done();
  490. }, 100);
  491. });
  492. Tinytest.addAsync(
  493. 'Client - Router - base path - route action called',
  494. function(test, done) {
  495. var simulatedBasePath = '/flow';
  496. var rand = Random.id();
  497. FlowRouter.route('/' + rand, {
  498. action: function() {
  499. resetBasePath();
  500. done();
  501. }
  502. });
  503. setBasePath(simulatedBasePath);
  504. FlowRouter.go('/' + rand);
  505. });
  506. Tinytest.add(
  507. 'Client - Router - base path - path generation',
  508. function(test, done) {
  509. _.each(['/flow', '/flow/', 'flow/', 'flow'], function(simulatedBasePath) {
  510. var rand = Random.id();
  511. setBasePath(simulatedBasePath);
  512. test.equal(FlowRouter.path('/' + rand), '/flow/' + rand);
  513. });
  514. resetBasePath();
  515. });
  516. function setBasePath(path) {
  517. FlowRouter._initialized = false;
  518. FlowRouter._basePath = path;
  519. FlowRouter.initialize();
  520. }
  521. var defaultBasePath = FlowRouter._basePath;
  522. function resetBasePath() {
  523. setBasePath(defaultBasePath);
  524. }
  525. function bind(obj, method) {
  526. return function() {
  527. obj[method].apply(obj, arguments);
  528. };
  529. }