summaryrefslogtreecommitdiffstats
path: root/packages/kadira-flow-router/test
diff options
context:
space:
mode:
authorLauri Ojansivu <x@xet7.org>2019-04-20 15:18:33 +0300
committerLauri Ojansivu <x@xet7.org>2019-04-20 15:18:33 +0300
commit73e265d8fd050ae3daa67472b4465a5c49d68910 (patch)
tree677b233934a43d8f873e24c794ce289d85e3a9b7 /packages/kadira-flow-router/test
parent6117097a93bfb11c8bd4c87a23c44a50e22ceb87 (diff)
downloadwekan-73e265d8fd050ae3daa67472b4465a5c49d68910.tar.gz
wekan-73e265d8fd050ae3daa67472b4465a5c49d68910.tar.bz2
wekan-73e265d8fd050ae3daa67472b4465a5c49d68910.zip
Include to Wekan packages directory contents, so that meteor command would build all directly.
This also simplifies build scripts. Thanks to xet7 !
Diffstat (limited to 'packages/kadira-flow-router/test')
-rw-r--r--packages/kadira-flow-router/test/client/_helpers.js10
-rw-r--r--packages/kadira-flow-router/test/client/group.spec.js113
-rw-r--r--packages/kadira-flow-router/test/client/loader.spec.js17
-rw-r--r--packages/kadira-flow-router/test/client/route.reactivity.spec.js158
-rw-r--r--packages/kadira-flow-router/test/client/router.core.spec.js632
-rw-r--r--packages/kadira-flow-router/test/client/router.reactivity.spec.js208
-rw-r--r--packages/kadira-flow-router/test/client/router.subs_ready.spec.js225
-rw-r--r--packages/kadira-flow-router/test/client/trigger.spec.js570
-rw-r--r--packages/kadira-flow-router/test/client/triggers.js297
-rw-r--r--packages/kadira-flow-router/test/common/fast_render_route.js48
-rw-r--r--packages/kadira-flow-router/test/common/group.spec.js16
-rw-r--r--packages/kadira-flow-router/test/common/route.spec.js15
-rw-r--r--packages/kadira-flow-router/test/common/router.addons.spec.js30
-rw-r--r--packages/kadira-flow-router/test/common/router.path.spec.js135
-rw-r--r--packages/kadira-flow-router/test/common/router.url.spec.js11
-rw-r--r--packages/kadira-flow-router/test/server/_helpers.js38
-rw-r--r--packages/kadira-flow-router/test/server/plugins/fast_render.js35
17 files changed, 2558 insertions, 0 deletions
diff --git a/packages/kadira-flow-router/test/client/_helpers.js b/packages/kadira-flow-router/test/client/_helpers.js
new file mode 100644
index 00000000..94376f00
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/_helpers.js
@@ -0,0 +1,10 @@
+GetSub = function (name) {
+ for(var id in Meteor.connection._subscriptions) {
+ var sub = Meteor.connection._subscriptions[id];
+ if(name === sub.name) {
+ return sub;
+ }
+ }
+};
+
+FlowRouter.route('/');
diff --git a/packages/kadira-flow-router/test/client/group.spec.js b/packages/kadira-flow-router/test/client/group.spec.js
new file mode 100644
index 00000000..06e793ba
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/group.spec.js
@@ -0,0 +1,113 @@
+Tinytest.add('Client - Group - validate path definition', function (test, next) {
+ // path & prefix must start with '/'
+ test.throws(function() {
+ new Group(null, {prefix: Random.id()});
+ });
+
+ var group = FlowRouter.group({prefix: '/' + Random.id()});
+
+ test.throws(function() {
+ group.route(Random.id());
+ });
+});
+
+Tinytest.addAsync('Client - Group - define and go to route with prefix', function (test, next) {
+ var prefix = Random.id();
+ var rand = Random.id();
+ var rendered = 0;
+
+ var group = FlowRouter.group({prefix: '/' + prefix});
+
+ group.route('/' + rand, {
+ action: function(_params) {
+ rendered++;
+ }
+ });
+
+ FlowRouter.go('/' + prefix + '/' + rand);
+
+ setTimeout(function() {
+ test.equal(rendered, 1);
+ setTimeout(next, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Group - define and go to route without prefix', function (test, next) {
+ var rand = Random.id();
+ var rendered = 0;
+
+ var group = FlowRouter.group();
+
+ group.route('/' + rand, {
+ action: function(_params) {
+ rendered++;
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(rendered, 1);
+ setTimeout(next, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Group - subscribe', function (test, next) {
+ var rand = Random.id();
+
+ var group = FlowRouter.group({
+ subscriptions: function (params) {
+ this.register('baz', Meteor.subscribe('baz'));
+ }
+ });
+
+ group.route('/' + rand);
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!!GetSub('baz'));
+ next();
+ }, 100);
+});
+
+
+Tinytest.addAsync('Client - Group - set and retrieve group name', function (test, next) {
+ var rand = Random.id();
+ var name = Random.id();
+
+ var group = FlowRouter.group({
+ name: name
+ });
+
+ group.route('/' + rand);
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(FlowRouter.current().route.group.name === name);
+ next();
+ }, 100);
+});
+
+Tinytest.add('Client - Group - expose group options on a route', function (test) {
+ var pathDef = "/" + Random.id();
+ var name = Random.id();
+ var groupName = Random.id();
+ var data = {aa: 10};
+ var layout = 'blah';
+
+ var group = FlowRouter.group({
+ name: groupName,
+ prefix: '/admin',
+ layout: layout,
+ someData: data
+ });
+
+ group.route(pathDef, {
+ name: name
+ });
+
+ var route = FlowRouter._routesMap[name];
+
+ test.equal(route.group.options.someData, data);
+ test.equal(route.group.options.layout, layout);
+});
diff --git a/packages/kadira-flow-router/test/client/loader.spec.js b/packages/kadira-flow-router/test/client/loader.spec.js
new file mode 100644
index 00000000..091c2e02
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/loader.spec.js
@@ -0,0 +1,17 @@
+Router = FlowRouter.Router;
+
+
+Tinytest.add('Client - import page.js', function (test) {
+ test.isTrue(!!Router.prototype._page);
+ test.isFalse(!!window.page);
+});
+
+
+Tinytest.add('Client - import query.js', function (test) {
+ test.isTrue(!!Router.prototype._qs);
+});
+
+
+Tinytest.add('Client - create FlowRouter', function (test) {
+ test.isTrue(!!FlowRouter);
+});
diff --git a/packages/kadira-flow-router/test/client/route.reactivity.spec.js b/packages/kadira-flow-router/test/client/route.reactivity.spec.js
new file mode 100644
index 00000000..c6c44183
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/route.reactivity.spec.js
@@ -0,0 +1,158 @@
+Route = FlowRouter.Route;
+
+
+Tinytest.addAsync('Client - Route - Reactivity - getParam', function (test, done) {
+ var r = new Route();
+ Tracker.autorun(function(c) {
+ var param = r.getParam("id");
+ if(param) {
+ test.equal(param, "hello");
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+
+ setTimeout(function() {
+ var context = {
+ params: {id: "hello"},
+ queryParams: {}
+ };
+ r.registerRouteChange(context);
+ }, 10);
+});
+
+Tinytest.addAsync('Client - Route - Reactivity - getParam on route close', function (test, done) {
+ var r = new Route();
+ var closeTriggered = false;
+ Tracker.autorun(function(c) {
+ var param = r.getParam("id");
+ if(closeTriggered) {
+ test.equal(param, undefined);
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+
+ setTimeout(function() {
+ closeTriggered = true;
+ r.registerRouteClose();
+ }, 10);
+});
+
+Tinytest.addAsync('Client - Route - Reactivity - getQueryParam', function (test, done) {
+ var r = new Route();
+ Tracker.autorun(function(c) {
+ var param = r.getQueryParam("id");
+ if(param) {
+ test.equal(param, "hello");
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+
+ setTimeout(function() {
+ var context = {
+ params: {},
+ queryParams: {id: "hello"}
+ };
+ r.registerRouteChange(context);
+ }, 10);
+});
+
+Tinytest.addAsync('Client - Route - Reactivity - getQueryParam on route close', function (test, done) {
+ var r = new Route();
+ var closeTriggered = false;
+ Tracker.autorun(function(c) {
+ var param = r.getQueryParam("id");
+ if(closeTriggered) {
+ test.equal(param, undefined);
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+
+ setTimeout(function() {
+ closeTriggered = true;
+ r.registerRouteClose();
+ }, 10);
+});
+
+Tinytest.addAsync('Client - Route - Reactivity - getRouteName rerun when route closed', function (test, done) {
+ var r = new Route();
+ r.name = "my-route";
+ var closeTriggered = false;
+
+ Tracker.autorun(function(c) {
+ var name = r.getRouteName();
+ test.equal(name, r.name);
+
+ if(closeTriggered) {
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+
+ setTimeout(function() {
+ closeTriggered = true;
+ r.registerRouteClose();
+ }, 10);
+});
+
+Tinytest.addAsync('Client - Route - Reactivity - watchPathChange when routeChange', function (test, done) {
+ var r = new Route();
+ var pathChangeCounts = 0;
+
+ var c = Tracker.autorun(function() {
+ r.watchPathChange();
+ pathChangeCounts++;
+ });
+
+ var context = {
+ params: {},
+ queryParams: {}
+ };
+
+ setTimeout(function() {
+ r.registerRouteChange(context);
+ setTimeout(checkAfterNormalRouteChange, 50);
+ }, 10);
+
+ function checkAfterNormalRouteChange() {
+ test.equal(pathChangeCounts, 2);
+ var lastRouteChange = true;
+ r.registerRouteChange(context, lastRouteChange);
+ setTimeout(checkAfterLastRouteChange, 10);
+ }
+
+ function checkAfterLastRouteChange() {
+ test.equal(pathChangeCounts, 2);
+ c.stop();
+ Meteor.defer(done);
+ }
+});
+
+Tinytest.addAsync('Client - Route - Reactivity - watchPathChange when routeClose', function (test, done) {
+ var r = new Route();
+ var pathChangeCounts = 0;
+
+ var c = Tracker.autorun(function() {
+ r.watchPathChange();
+ pathChangeCounts++;
+ });
+
+ var context = {
+ params: {},
+ queryParams: {}
+ };
+
+ setTimeout(function() {
+ r.registerRouteClose();
+ setTimeout(checkAfterRouteClose, 10);
+ }, 10);
+
+ function checkAfterRouteClose() {
+ test.equal(pathChangeCounts, 2);
+ c.stop();
+ Meteor.defer(done);
+ }
+}); \ No newline at end of file
diff --git a/packages/kadira-flow-router/test/client/router.core.spec.js b/packages/kadira-flow-router/test/client/router.core.spec.js
new file mode 100644
index 00000000..160c9112
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/router.core.spec.js
@@ -0,0 +1,632 @@
+Router = FlowRouter.Router;
+
+Tinytest.addAsync('Client - Router - define and go to route', function (test, next) {
+ var rand = Random.id();
+ var rendered = 0;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ rendered++;
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(rendered, 1);
+ setTimeout(next, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - define and go to route with fields',
+function (test, next) {
+ var rand = Random.id();
+ var pathDef = "/" + rand + "/:key";
+ var rendered = 0;
+
+ FlowRouter.route(pathDef, {
+ action: function(params) {
+ test.equal(params.key, "abc +@%");
+ rendered++;
+ }
+ });
+
+ FlowRouter.go(pathDef, {key: "abc +@%"});
+
+ setTimeout(function() {
+ test.equal(rendered, 1);
+ setTimeout(next, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - parse params and query', function (test, next) {
+ var rand = Random.id();
+ var rendered = 0;
+ var params = null;
+
+ FlowRouter.route('/' + rand + '/:foo', {
+ action: function(_params) {
+ rendered++;
+ params = _params;
+ }
+ });
+
+ FlowRouter.go('/' + rand + '/bar');
+
+ setTimeout(function() {
+ test.equal(rendered, 1);
+ test.equal(params.foo, 'bar');
+ setTimeout(next, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - redirect using FlowRouter.go', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var paths = ['/' + rand2, '/' + rand];
+ var done = false;
+
+ FlowRouter.route(paths[0], {
+ action: function(_params) {
+ log.push(1);
+ FlowRouter.go(paths[1]);
+ }
+ });
+
+ FlowRouter.route(paths[1], {
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.go(paths[0]);
+
+ setTimeout(function() {
+ test.equal(log, [1, 2]);
+ done = true;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - get current route path', function (test, next) {
+ var value = Random.id();
+ var randomValue = Random.id();
+ var pathDef = "/" + randomValue + '/:_id';
+ var path = "/" + randomValue + "/" + value;
+
+ var detectedValue = null;
+
+ FlowRouter.route(pathDef, {
+ action: function(params) {
+ detectedValue = params._id;
+ }
+ });
+
+ FlowRouter.go(path);
+
+ Meteor.setTimeout(function() {
+ test.equal(detectedValue, value);
+ test.equal(FlowRouter.current().path, path);
+ next();
+ }, 50);
+});
+
+Tinytest.addAsync('Client - Router - subscribe to global subs', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand);
+
+ FlowRouter.subscriptions = function (path) {
+ test.equal(path, '/' + rand);
+ this.register('baz', Meteor.subscribe('baz'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!!GetSub('baz'));
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - setParams - generic', function (test, done) {
+ var randomKey = Random.id();
+ var pathDef = "/" + randomKey + "/:cat/:id";
+ var paramsList = [];
+ FlowRouter.route(pathDef, {
+ action: function(params) {
+ paramsList.push(params);
+ }
+ });
+
+ FlowRouter.go(pathDef, {cat: "meteor", id: "200"});
+ setTimeout(function() {
+ // return done();
+ var success = FlowRouter.setParams({id: "700"});
+ test.isTrue(success);
+ setTimeout(validate, 50);
+ }, 50);
+
+ function validate() {
+ test.equal(paramsList.length, 2);
+ test.equal(_.pick(paramsList[0], "id", "cat"), {cat: "meteor", id: "200"});
+ test.equal(_.pick(paramsList[1], "id", "cat"), {cat: "meteor", id: "700"});
+ done();
+ }
+});
+
+Tinytest.addAsync('Client - Router - setParams - preserve query strings', function (test, done) {
+ var randomKey = Random.id();
+ var pathDef = "/" + randomKey + "/:cat/:id";
+ var paramsList = [];
+ var queryParamsList = [];
+
+ FlowRouter.route(pathDef, {
+ action: function(params, queryParams) {
+ paramsList.push(params);
+ queryParamsList.push(queryParams);
+ }
+ });
+
+ FlowRouter.go(pathDef, {cat: "meteor", id: "200 +% / ad"}, {aa: "20 +%"});
+ setTimeout(function() {
+ // return done();
+ var success = FlowRouter.setParams({id: "700 +% / ad"});
+ test.isTrue(success);
+ setTimeout(validate, 50);
+ }, 50);
+
+ function validate() {
+ test.equal(paramsList.length, 2);
+ test.equal(queryParamsList.length, 2);
+
+ test.equal(_.pick(paramsList[0], "id", "cat"), {cat: "meteor", id: "200 +% / ad"});
+ test.equal(_.pick(paramsList[1], "id", "cat"), {cat: "meteor", id: "700 +% / ad"});
+ test.equal(queryParamsList, [{aa: "20 +%"}, {aa: "20 +%"}]);
+ done();
+ }
+});
+
+Tinytest.add('Client - Router - setParams - no route selected', function (test) {
+ var originalRoute = FlowRouter._current.route;
+ FlowRouter._current.route = undefined;
+ var success = FlowRouter.setParams({id: "800"});
+ test.isFalse(success);
+ FlowRouter._current.route = originalRoute;
+});
+
+Tinytest.addAsync('Client - Router - setQueryParams - using check', function (test, done) {
+ var randomKey = Random.id();
+ var pathDef = "/" + randomKey + "";
+ var queryParamsList = [];
+ FlowRouter.route(pathDef, {
+ action: function(params, queryParams) {
+ queryParamsList.push(queryParams);
+ }
+ });
+
+ FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
+ setTimeout(function() {
+ check(FlowRouter.current().queryParams, {cat: String, id: String});
+ done();
+ }, 50);
+});
+
+Tinytest.addAsync('Client - Router - setQueryParams - generic', function (test, done) {
+ var randomKey = Random.id();
+ var pathDef = "/" + randomKey + "";
+ var queryParamsList = [];
+ FlowRouter.route(pathDef, {
+ action: function(params, queryParams) {
+ queryParamsList.push(queryParams);
+ }
+ });
+
+ FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
+ setTimeout(function() {
+ // return done();
+ var success = FlowRouter.setQueryParams({id: "700"});
+ test.isTrue(success);
+ setTimeout(validate, 50);
+ }, 50);
+
+ function validate() {
+ test.equal(queryParamsList.length, 2);
+ test.equal(_.pick(queryParamsList[0], "id", "cat"), {cat: "meteor", id: "200"});
+ test.equal(_.pick(queryParamsList[1], "id", "cat"), {cat: "meteor", id: "700"});
+ done();
+ }
+});
+
+Tinytest.addAsync('Client - Router - setQueryParams - remove query param null', function (test, done) {
+ var randomKey = Random.id();
+ var pathDef = "/" + randomKey + "";
+ var queryParamsList = [];
+ FlowRouter.route(pathDef, {
+ action: function(params, queryParams) {
+ queryParamsList.push(queryParams);
+ }
+ });
+
+ FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
+ setTimeout(function() {
+ var success = FlowRouter.setQueryParams({id: "700", cat: null});
+ test.isTrue(success);
+ setTimeout(validate, 50);
+ }, 50);
+
+ function validate() {
+ test.equal(queryParamsList.length, 2);
+ test.equal(_.pick(queryParamsList[0], "id", "cat"), {cat: "meteor", id: "200"});
+ test.equal(queryParamsList[1], {id: "700"});
+ done();
+ }
+});
+
+Tinytest.addAsync('Client - Router - setQueryParams - remove query param undefined', function (test, done) {
+ var randomKey = Random.id();
+ var pathDef = "/" + randomKey + "";
+ var queryParamsList = [];
+ FlowRouter.route(pathDef, {
+ action: function(params, queryParams) {
+ queryParamsList.push(queryParams);
+ }
+ });
+
+ FlowRouter.go(pathDef, {}, {cat: "meteor", id: "200"});
+ setTimeout(function() {
+ var success = FlowRouter.setQueryParams({id: "700", cat: undefined});
+ test.isTrue(success);
+ setTimeout(validate, 50);
+ }, 50);
+
+ function validate() {
+ test.equal(queryParamsList.length, 2);
+ test.equal(_.pick(queryParamsList[0], "id", "cat"), {cat: "meteor", id: "200"});
+ test.equal(queryParamsList[1], {id: "700"});
+ done();
+ }
+});
+
+Tinytest.addAsync('Client - Router - setQueryParams - preserve params', function (test, done) {
+ var randomKey = Random.id();
+ var pathDef = "/" + randomKey + "/:abc";
+ var queryParamsList = [];
+ var paramsList = [];
+ FlowRouter.route(pathDef, {
+ action: function(params, queryParams) {
+ paramsList.push(params);
+ queryParamsList.push(queryParams);
+ }
+ });
+
+ FlowRouter.go(pathDef, {abc: "20"}, {cat: "meteor", id: "200"});
+ setTimeout(function() {
+ // return done();
+ var success = FlowRouter.setQueryParams({id: "700"});
+ test.isTrue(success);
+ setTimeout(validate, 50);
+ }, 50);
+
+ function validate() {
+ test.equal(queryParamsList.length, 2);
+ test.equal(queryParamsList, [
+ {cat: "meteor", id: "200"}, {cat: "meteor", id: "700"}
+ ]);
+
+ test.equal(paramsList.length, 2);
+ test.equal(_.pick(paramsList[0], "abc"), {abc: "20"});
+ test.equal(_.pick(paramsList[1], "abc"), {abc: "20"});
+ done();
+ }
+});
+
+Tinytest.add('Client - Router - setQueryParams - no route selected', function (test) {
+ var originalRoute = FlowRouter._current.route;
+ FlowRouter._current.route = undefined;
+ var success = FlowRouter.setQueryParams({id: "800"});
+ test.isFalse(success);
+ FlowRouter._current.route = originalRoute;
+});
+
+Tinytest.addAsync('Client - Router - notFound', function (test, done) {
+ var data = [];
+ FlowRouter.notFound = {
+ subscriptions: function() {
+ data.push("subscriptions");
+ },
+ action: function() {
+ data.push("action");
+ }
+ };
+
+ FlowRouter.go("/" + Random.id());
+ setTimeout(function() {
+ test.equal(data, ["subscriptions", "action"]);
+ done();
+ }, 50);
+});
+
+Tinytest.addAsync('Client - Router - withReplaceState - enabled',
+function (test, done) {
+ var pathDef = "/" + Random.id() + "/:id";
+ var originalRedirect = FlowRouter._page.replace;
+ var callCount = 0;
+ FlowRouter._page.replace = function(path) {
+ callCount++;
+ originalRedirect.call(FlowRouter._page, path);
+ };
+
+ FlowRouter.route(pathDef, {
+ name: name,
+ action: function(params) {
+ test.equal(params.id, "awesome");
+ test.equal(callCount, 1);
+ FlowRouter._page.replace = originalRedirect;
+ // We don't use Meteor.defer here since it carries
+ // Meteor.Environment vars too
+ // Which breaks our test below
+ setTimeout(done, 0);
+ }
+ });
+
+ FlowRouter.withReplaceState(function() {
+ FlowRouter.go(pathDef, {id: "awesome"});
+ });
+});
+
+Tinytest.addAsync('Client - Router - withReplaceState - disabled',
+function (test, done) {
+ var pathDef = "/" + Random.id() + "/:id";
+ var originalRedirect = FlowRouter._page.replace;
+ var callCount = 0;
+ FlowRouter._page.replace = function(path) {
+ callCount++;
+ originalRedirect.call(FlowRouter._page, path);
+ };
+
+ FlowRouter.route(pathDef, {
+ name: name,
+ action: function(params) {
+ test.equal(params.id, "awesome");
+ test.equal(callCount, 0);
+ FlowRouter._page.replace = originalRedirect;
+ Meteor.defer(done);
+ }
+ });
+
+ FlowRouter.go(pathDef, {id: "awesome"});
+});
+
+Tinytest.addAsync('Client - Router - withTrailingSlash - enabled', function (test, next) {
+ var rand = Random.id();
+ var rendered = 0;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ rendered++;
+ }
+ });
+
+ FlowRouter.withTrailingSlash(function() {
+ FlowRouter.go('/' + rand);
+ });
+
+ setTimeout(function() {
+ test.equal(rendered, 1);
+ test.equal(_.last(location.href), '/');
+ setTimeout(next, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - idempotent routing - action',
+function (test, done) {
+ var rand = Random.id();
+ var pathDef = "/" + rand;
+ var rendered = 0;
+
+ FlowRouter.route(pathDef, {
+ action: function(params) {
+ rendered++;
+ }
+ });
+
+ FlowRouter.go(pathDef);
+
+ Meteor.defer(function() {
+ FlowRouter.go(pathDef);
+
+ Meteor.defer(function() {
+ test.equal(rendered, 1);
+ done();
+ });
+ });
+});
+
+Tinytest.addAsync('Client - Router - idempotent routing - triggers',
+function (test, next) {
+ var rand = Random.id();
+ var pathDef = "/" + rand;
+ var runnedTriggers = 0;
+ var done = false;
+
+ var triggerFns = [function(params) {
+ if (done) return;
+
+ runnedTriggers++;
+ }];
+
+ FlowRouter.triggers.enter(triggerFns);
+
+ FlowRouter.route(pathDef, {
+ triggersEnter: triggerFns,
+ triggersExit: triggerFns
+ });
+
+ FlowRouter.go(pathDef);
+
+ FlowRouter.triggers.exit(triggerFns);
+
+ Meteor.defer(function() {
+ FlowRouter.go(pathDef);
+
+ Meteor.defer(function() {
+ test.equal(runnedTriggers, 2);
+ done = true;
+ next();
+ });
+ });
+});
+
+Tinytest.addAsync('Client - Router - reload - action',
+function (test, done) {
+ var rand = Random.id();
+ var pathDef = "/" + rand;
+ var rendered = 0;
+
+ FlowRouter.route(pathDef, {
+ action: function(params) {
+ rendered++;
+ }
+ });
+
+ FlowRouter.go(pathDef);
+
+ Meteor.defer(function() {
+ FlowRouter.reload();
+
+ Meteor.defer(function() {
+ test.equal(rendered, 2);
+ done();
+ });
+ });
+});
+
+Tinytest.addAsync('Client - Router - reload - triggers',
+function (test, next) {
+ var rand = Random.id();
+ var pathDef = "/" + rand;
+ var runnedTriggers = 0;
+ var done = false;
+
+ var triggerFns = [function(params) {
+ if (done) return;
+
+ runnedTriggers++;
+ }];
+
+ FlowRouter.triggers.enter(triggerFns);
+
+ FlowRouter.route(pathDef, {
+ triggersEnter: triggerFns,
+ triggersExit: triggerFns
+ });
+
+ FlowRouter.go(pathDef);
+
+ FlowRouter.triggers.exit(triggerFns);
+
+ Meteor.defer(function() {
+ FlowRouter.reload();
+
+ Meteor.defer(function() {
+ test.equal(runnedTriggers, 6);
+ done = true;
+ next();
+ });
+ });
+});
+
+Tinytest.addAsync(
+'Client - Router - wait - before initialize',
+function(test, done) {
+ FlowRouter._initialized = false;
+ FlowRouter.wait();
+ test.equal(FlowRouter._askedToWait, true);
+
+ FlowRouter._initialized = true;
+ FlowRouter._askedToWait = false;
+ done();
+});
+
+Tinytest.addAsync(
+'Client - Router - wait - after initialized',
+function(test, done) {
+ try {
+ FlowRouter.wait();
+ } catch(ex) {
+ test.isTrue(/can't wait/.test(ex.message));
+ done();
+ }
+});
+
+Tinytest.addAsync(
+'Client - Router - initialize - after initialized',
+function(test, done) {
+ try {
+ FlowRouter.initialize();
+ } catch(ex) {
+ test.isTrue(/already initialized/.test(ex.message));
+ done();
+ }
+});
+
+Tinytest.addAsync(
+'Client - Router - base path - url updated',
+function(test, done) {
+ var simulatedBasePath = '/flow';
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, { action: function() {} });
+
+ setBasePath(simulatedBasePath);
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.equal(location.pathname, simulatedBasePath + '/' + rand);
+ resetBasePath();
+ done();
+ }, 100);
+});
+
+Tinytest.addAsync(
+'Client - Router - base path - route action called',
+function(test, done) {
+ var simulatedBasePath = '/flow';
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ action: function() {
+ resetBasePath();
+ done();
+ }
+ });
+
+ setBasePath(simulatedBasePath);
+ FlowRouter.go('/' + rand);
+});
+
+Tinytest.add(
+'Client - Router - base path - path generation',
+function(test, done) {
+ _.each(['/flow', '/flow/', 'flow/', 'flow'], function(simulatedBasePath) {
+ var rand = Random.id();
+ setBasePath(simulatedBasePath);
+ test.equal(FlowRouter.path('/' + rand), '/flow/' + rand);
+ });
+ resetBasePath();
+});
+
+
+function setBasePath(path) {
+ FlowRouter._initialized = false;
+ FlowRouter._basePath = path;
+ FlowRouter.initialize();
+}
+
+var defaultBasePath = FlowRouter._basePath;
+function resetBasePath() {
+ setBasePath(defaultBasePath);
+}
+
+function bind(obj, method) {
+ return function() {
+ obj[method].apply(obj, arguments);
+ };
+}
diff --git a/packages/kadira-flow-router/test/client/router.reactivity.spec.js b/packages/kadira-flow-router/test/client/router.reactivity.spec.js
new file mode 100644
index 00000000..b06deeda
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/router.reactivity.spec.js
@@ -0,0 +1,208 @@
+Tinytest.addAsync(
+'Client - Router - Reactivity - detectChange only once',
+function (test, done) {
+ var route = "/" + Random.id();
+ var name = Random.id();
+ FlowRouter.route(route, {name: name});
+
+ var ranCount = 0;
+ var pickedId = null;
+ var c = Tracker.autorun(function() {
+ ranCount++;
+ pickedId = FlowRouter.getQueryParam("id");
+ if(pickedId) {
+ test.equal(pickedId, "hello");
+ test.equal(ranCount, 2);
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+
+ setTimeout(function() {
+ FlowRouter.go(name, {}, {id: "hello"});
+ }, 2);
+});
+
+Tinytest.addAsync(
+'Client - Router - Reactivity - detectChange in the action',
+function (test, done) {
+ var route = "/" + Random.id();
+ var name = Random.id();
+ FlowRouter.route(route, {
+ name: name,
+ action: function() {
+ var id = FlowRouter.getQueryParam("id");
+ test.equal(id, "hello");
+ Meteor.defer(done);
+ }
+ });
+
+ setTimeout(function() {
+ FlowRouter.go(name, {}, {id: "hello"});
+ }, 2);
+});
+
+Tinytest.addAsync(
+'Client - Router - Reactivity - detect prev routeChange after new action',
+function (test, done) {
+ var route1 = "/" + Random.id();
+ var name1 = Random.id();
+ var pickedName1 = null;
+
+ var route2 = "/" + Random.id();
+ var name2 = Random.id();
+ var pickedName2 = Random.id();
+
+ FlowRouter.route(route1, {
+ name: name1,
+ action: function() {
+ Tracker.autorun(function(c) {
+ pickedName1 = FlowRouter.getRouteName();
+ if(pickedName1 == name2) {
+ test.equal(pickedName1, pickedName2);
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+ }
+ });
+
+ FlowRouter.route(route2, {
+ name: name2,
+ action: function() {
+ pickedName2 = FlowRouter.getRouteName();
+ test.equal(pickedName1, name1);
+ test.equal(pickedName2, name2);
+ }
+ });
+
+ FlowRouter.go(name1);
+ Meteor.setTimeout(function() {
+ FlowRouter.go(name2);
+ }, 10);
+});
+
+Tinytest.addAsync(
+'Client - Router - Reactivity - defer watchPathChange until new route rendered',
+function(test, done) {
+ var route1 = "/" + Random.id();
+ var name1 = Random.id();
+ var pickedName1 = null;
+
+ var route2 = "/" + Random.id();
+ var name2 = Random.id();
+ var pickedName2 = Random.id();
+
+ FlowRouter.route(route1, {
+ name: name1,
+ action: function() {
+ Tracker.autorun(function(c) {
+ FlowRouter.watchPathChange();
+ pickedName1 = FlowRouter.current().route.name;
+ if(pickedName1 == name2) {
+ test.equal(pickedName1, pickedName2);
+ c.stop();
+ Meteor.defer(done);
+ }
+ });
+ }
+ });
+
+ FlowRouter.route(route2, {
+ name: name2,
+ action: function() {
+ pickedName2 = FlowRouter.current().route.name;
+ test.equal(pickedName1, name1);
+ test.equal(pickedName2, name2);
+ }
+ });
+
+ FlowRouter.go(name1);
+ Meteor.setTimeout(function() {
+ FlowRouter.go(name2);
+ }, 10);
+});
+
+Tinytest.addAsync(
+'Client - Router - Reactivity - reactive changes and trigger redirects',
+function(test, done) {
+ var name1 = Random.id();
+ var route1 = "/" + name1;
+ FlowRouter.route(route1, {
+ name: name1
+ });
+
+ var name2 = Random.id();
+ var route2 = "/" + name2;
+ FlowRouter.route(route2, {
+ name: name2,
+ triggersEnter: [function(context, redirect) {
+ redirect(name3);
+ }]
+ });
+
+
+ var name3 = Random.id();
+ var route3 = "/" + name3;
+ FlowRouter.route(route3, {
+ name: name3
+ });
+
+ var routeNamesFired = [];
+ FlowRouter.go(name1);
+
+ var c = null;
+ setTimeout(function() {
+ c = Tracker.autorun(function(c) {
+ routeNamesFired.push(FlowRouter.getRouteName());
+ });
+ FlowRouter.go(name2);
+ }, 50);
+
+ setTimeout(function() {
+ c.stop();
+ test.equal(routeNamesFired, [name1, name3]);
+ Meteor.defer(done);
+ }, 250);
+});
+
+Tinytest.addAsync(
+'Client - Router - Reactivity - watchPathChange for every route change',
+function(test, done) {
+ var route1 = "/" + Random.id();
+ var name1 = Random.id();
+ var pickedName1 = null;
+
+ var route2 = "/" + Random.id();
+ var name2 = Random.id();
+ var pickedName2 = Random.id();
+
+ FlowRouter.route(route1, {
+ name: name1
+ });
+
+ FlowRouter.route(route2, {
+ name: name2
+ });
+
+ var ids = [];
+ var c = Tracker.autorun(function() {
+ FlowRouter.watchPathChange();
+ ids.push(FlowRouter.current().queryParams['id']);
+ });
+
+ FlowRouter.go(name1, {}, {id: "one"});
+ Meteor.setTimeout(function() {
+ FlowRouter.go(name1, {}, {id: "two"});
+ }, 10);
+
+ Meteor.setTimeout(function() {
+ FlowRouter.go(name2, {}, {id: "three"});
+ }, 20);
+
+ Meteor.setTimeout(function() {
+ test.equal(ids, [undefined, "one", "two", "three"]);
+ c.stop();
+ done();
+ }, 40);
+}); \ No newline at end of file
diff --git a/packages/kadira-flow-router/test/client/router.subs_ready.spec.js b/packages/kadira-flow-router/test/client/router.subs_ready.spec.js
new file mode 100644
index 00000000..8a20077a
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/router.subs_ready.spec.js
@@ -0,0 +1,225 @@
+Tinytest.addAsync('Client - Router - subsReady - with no args - all subscriptions ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('bar', Meteor.subscribe('bar'));
+ this.register('foo', Meteor.subscribe('foo'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('baz', Meteor.subscribe('baz'));
+ };
+
+ FlowRouter.go('/' + rand);
+
+ Tracker.autorun(function(c) {
+ if(FlowRouter.subsReady()) {
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ c.stop();
+ }
+ });
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with no args - all subscriptions does not ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('fooNotReady', Meteor.subscribe('fooNotReady'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('bazNotReady', Meteor.subscribe('bazNotReady'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!FlowRouter.subsReady());
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with no args - global subscriptions does not ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('bar', Meteor.subscribe('bar'));
+ this.register('foo', Meteor.subscribe('foo'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('bazNotReady', Meteor.subscribe('bazNotReady'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!FlowRouter.subsReady());
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with no args - current subscriptions does not ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('bar', Meteor.subscribe('bar'));
+ this.register('fooNotReady', Meteor.subscribe('fooNotReady'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('baz', Meteor.subscribe('baz'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!FlowRouter.subsReady());
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with args - all subscriptions ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('bar', Meteor.subscribe('bar'));
+ this.register('foo', Meteor.subscribe('foo'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('baz', Meteor.subscribe('baz'));
+ };
+
+ FlowRouter.go('/' + rand);
+ Tracker.autorun(function(c) {
+ if(FlowRouter.subsReady('foo', 'baz')) {
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ c.stop();
+ }
+ });
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with args - all subscriptions does not ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('fooNotReady', Meteor.subscribe('fooNotReady'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('bazNotReady', Meteor.subscribe('bazNotReady'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!FlowRouter.subsReady('fooNotReady', 'bazNotReady'));
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with args - global subscriptions does not ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('bar', Meteor.subscribe('bar'));
+ this.register('foo', Meteor.subscribe('foo'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('bazNotReady', Meteor.subscribe('bazNotReady'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!FlowRouter.subsReady('foo', 'bazNotReady'));
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with args - current subscriptions does not ready', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('bar', Meteor.subscribe('bar'));
+ this.register('fooNotReady', Meteor.subscribe('fooNotReady'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('baz', Meteor.subscribe('baz'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!FlowRouter.subsReady('fooNotReady', 'baz'));
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with args - subscribe with wrong name', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ this.register('bar', Meteor.subscribe('bar'));
+ }
+ });
+
+ FlowRouter.subscriptions = function () {
+ this.register('baz', Meteor.subscribe('baz'));
+ };
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(!FlowRouter.subsReady('baz', 'xxx', 'baz'));
+ FlowRouter.subscriptions = Function.prototype;
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - with args - same route two different subs', function (test, next) {
+ var rand = Random.id();
+ var count = 0;
+ FlowRouter.route('/' + rand, {
+ subscriptions: function(params) {
+ if(++count == 1) {
+ this.register('not-exisitng', Meteor.subscribe('not-exisitng'));
+ }
+ }
+ });
+
+ FlowRouter.subscriptions = Function.prototype;
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isFalse(FlowRouter.subsReady());
+ FlowRouter.go('/' + rand, {}, {param: "111"});
+ setTimeout(function() {
+ test.isTrue(FlowRouter.subsReady());
+ next();
+ }, 100)
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Router - subsReady - no subscriptions - simple', function (test, next) {
+ var rand = Random.id();
+ FlowRouter.route('/' + rand, {});
+ FlowRouter.subscriptions = Function.prototype;
+
+ FlowRouter.go('/' + rand);
+ setTimeout(function() {
+ test.isTrue(FlowRouter.subsReady());
+ next();
+ }, 100);
+}); \ No newline at end of file
diff --git a/packages/kadira-flow-router/test/client/trigger.spec.js b/packages/kadira-flow-router/test/client/trigger.spec.js
new file mode 100644
index 00000000..319c6bd2
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/trigger.spec.js
@@ -0,0 +1,570 @@
+Tinytest.addAsync('Client - Triggers - global enter triggers', function(test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var paths = ['/' + rand2, '/' + rand];
+ var done = false;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.route('/' + rand2, {
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.triggers.enter([function(context) {
+ if(done) return;
+ test.equal(context.path, paths.pop());
+ log.push(0);
+ }]);
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [0, 1, 0, 2]);
+ done = true;
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - global enter triggers with "only"', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var done = false;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.route('/' + rand2, {
+ name: 'foo',
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.triggers.enter([function(context) {
+ if(done) return;
+ test.equal(context.path, '/' + rand2);
+ log.push(8);
+ }], {only: ['foo']});
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [1, 8, 2]);
+ done = true;
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - global enter triggers with "except"', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var done = false;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.route('/' + rand2, {
+ name: 'foo',
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.triggers.enter([function(context) {
+ if(done) return;
+ test.equal(context.path, '/' + rand);
+ log.push(8);
+ }], {except: ['foo']});
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [8, 1, 2]);
+ done = true;
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - global exit triggers', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var done =false;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.route('/' + rand2, {
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ FlowRouter.triggers.exit([function(context) {
+ if(done) return;
+ test.equal(context.path, '/' + rand);
+ log.push(0);
+ }]);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [1, 0, 2]);
+ done = true;
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - global exit triggers with "only"', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var done = false;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.route('/' + rand2, {
+ name: 'foo',
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.triggers.exit([function(context) {
+ if(done) return;
+ test.equal(context.path, '/' + rand2);
+ log.push(8);
+ }], {only: ['foo']});
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(log, [1, 2, 8, 1]);
+ done = true;
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - global exit triggers with "except"', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var done = false;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.route('/' + rand2, {
+ name: 'foo',
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ FlowRouter.triggers.exit([function(context) {
+ if(done) return;
+ test.equal(context.path, '/' + rand);
+ log.push(9);
+ }], {except: ['foo']});
+
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(log, [1, 9, 2, 1]);
+ done = true;
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - route enter triggers', function (test, next) {
+ var rand = Random.id();
+ var log = [];
+
+ var triggerFn = function (context) {
+ test.equal(context.path, '/' + rand);
+ log.push(5);
+ };
+
+ FlowRouter.route('/' + rand, {
+ triggersEnter: [triggerFn],
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(log, [5, 1]);
+ setTimeout(next, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - router exit triggers', function (test, next) {
+ var rand = Random.id();
+ var log = [];
+
+ var triggerFn = function (context) {
+ test.equal(context.path, '/' + rand);
+ log.push(6);
+ };
+
+ FlowRouter.route('/' + rand, {
+ triggersExit: [triggerFn],
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + Random.id());
+
+ setTimeout(function() {
+ test.equal(log, [1, 6]);
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - group enter triggers', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var paths = ['/' + rand2, '/' + rand];
+
+ var triggerFn = function (context) {
+ test.equal(context.path, paths.pop());
+ log.push(3);
+ };
+
+ var group = FlowRouter.group({
+ triggersEnter: [triggerFn]
+ });
+
+ group.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ group.route('/' + rand2, {
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [3, 1, 3, 2]);
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - group exit triggers', function (test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+
+ var triggerFn = function (context) {
+ log.push(4);
+ };
+
+ var group = FlowRouter.group({
+ triggersExit: [triggerFn]
+ });
+
+ group.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ group.route('/' + rand2, {
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [1, 4, 2]);
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - redirect from enter', function(test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+
+ FlowRouter.route('/' + rand, {
+ triggersEnter: [function(context, redirect) {
+ redirect("/" + rand2);
+ }, function() {
+ throw new Error("should not execute this trigger");
+ }],
+ action: function(_params) {
+ log.push(1);
+ },
+ name: rand
+ });
+
+ FlowRouter.route('/' + rand2, {
+ action: function(_params) {
+ log.push(2);
+ },
+ name: rand2
+ });
+
+ FlowRouter.go('/');
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(log, [2]);
+ next();
+ }, 300);
+});
+
+Tinytest.addAsync('Client - Triggers - redirect by routeName', function(test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+
+ FlowRouter.route('/' + rand, {
+ name: rand,
+ triggersEnter: [function(context, redirect) {
+ redirect(rand2, null, {aa: "bb"});
+ }, function() {
+ throw new Error("should not execute this trigger");
+ }],
+ action: function(_params) {
+ log.push(1);
+ },
+ name: rand
+ });
+
+ FlowRouter.route('/' + rand2, {
+ name: rand2,
+ action: function(_params, queryParams) {
+ log.push(2);
+ test.equal(queryParams, {aa: "bb"});
+ },
+ name: rand2
+ });
+
+ FlowRouter.go('/');
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(log, [2]);
+ next();
+ }, 300);
+});
+
+Tinytest.addAsync('Client - Triggers - redirect from exit', function(test, next) {
+ var rand = Random.id(), rand2 = Random.id(), rand3 = Random.id();
+ var log = [];
+
+ FlowRouter.route('/' + rand, {
+ action: function() {
+ log.push(1);
+ },
+ triggersExit: [
+ function(context, redirect) {
+ redirect('/' + rand3);
+ },
+ function() {
+ throw new Error("should not call this trigger");
+ }
+ ]
+ });
+
+ FlowRouter.route('/' + rand2, {
+ action: function() {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.route('/' + rand3, {
+ action: function() {
+ log.push(3);
+ }
+ });
+
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [1, 3]);
+ next();
+ }, 100);
+ }, 100);
+});
+
+Tinytest.addAsync('Client - Triggers - redirect to external URL fails', function(test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+
+ // testing "http://" URLs
+ FlowRouter.route('/' + rand, {
+ triggersEnter: [function(context, redirect) {
+ test.throws(function() {
+ redirect("http://example.com/")
+ }, "Redirects to URLs outside of the app are not supported")
+ }],
+ action: function(_params) {
+ log.push(1);
+ },
+ name: rand
+ });
+
+ // testing "https://" URLs
+ FlowRouter.route('/' + rand2, {
+ triggersEnter: [function(context, redirect) {
+ test.throws(function() {
+ redirect("https://example.com/")
+ })
+ }],
+ action: function(_params) {
+ log.push(2);
+ },
+ name: rand2
+ });
+
+ FlowRouter.go('/');
+ FlowRouter.go('/' + rand);
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, []);
+ next();
+ }, 300);
+});
+
+Tinytest.addAsync('Client - Triggers - stop callback from enter', function(test, next) {
+ var rand = Random.id();
+ var log = [];
+
+ FlowRouter.route('/' + rand, {
+ triggersEnter: [function(context, redirect, stop) {
+ log.push(10);
+ stop();
+ }, function() {
+ throw new Error("should not execute this trigger");
+ }],
+ action: function(_params) {
+ throw new Error("should not execute the action");
+ }
+ });
+
+ FlowRouter.go('/');
+ FlowRouter.go('/' + rand);
+
+ setTimeout(function() {
+ test.equal(log, [10]);
+ next();
+ }, 100);
+});
+
+Tinytest.addAsync(
+'Client - Triggers - invalidate inside an autorun',
+function(test, next) {
+ var rand = Random.id(), rand2 = Random.id();
+ var log = [];
+ var paths = ['/' + rand2, '/' + rand];
+ var done = false;
+
+ FlowRouter.route('/' + rand, {
+ action: function(_params) {
+ log.push(1);
+ }
+ });
+
+ FlowRouter.route('/' + rand2, {
+ action: function(_params) {
+ log.push(2);
+ }
+ });
+
+ FlowRouter.triggers.enter([function(context) {
+ if(done) return;
+ test.equal(context.path, paths.pop());
+ log.push(0);
+ }]);
+
+ Tracker.autorun(function(c) {
+ FlowRouter.go('/' + rand);
+ });
+
+ setTimeout(function() {
+ FlowRouter.go('/' + rand2);
+
+ setTimeout(function() {
+ test.equal(log, [0, 1, 0, 2]);
+ done = true;
+ setTimeout(next, 100);
+ }, 100);
+ }, 100);
+});
diff --git a/packages/kadira-flow-router/test/client/triggers.js b/packages/kadira-flow-router/test/client/triggers.js
new file mode 100644
index 00000000..7eb9a99c
--- /dev/null
+++ b/packages/kadira-flow-router/test/client/triggers.js
@@ -0,0 +1,297 @@
+Tinytest.addAsync(
+'Triggers - runTriggers - run all and after',
+function(test, done) {
+ var store = [];
+ var triggers = MakeTriggers(2, store);
+ Triggers.runTriggers(triggers, null, null, function() {
+ test.equal(store, [0, 1]);
+ done();
+ });
+});
+
+Tinytest.addAsync(
+'Triggers - runTriggers - redirect with url',
+function(test, done) {
+ var store = [];
+ var url = "http://google.com";
+ var triggers = MakeTriggers(2, store);
+ triggers.splice(1, 0, function(context, redirect) {
+ redirect(url);
+ });
+
+ Triggers.runTriggers(triggers, null, function(u) {
+ test.equal(store, [0]);
+ test.equal(u, url);
+ done();
+ }, null);
+});
+
+Tinytest.addAsync(
+'Triggers - runTriggers - redirect without url',
+function(test, done) {
+ var store = [];
+ var url = "http://google.com";
+ var triggers = MakeTriggers(2, store);
+ triggers.splice(1, 0, function(context, redirect) {
+ try {
+ redirect();
+ } catch(ex) {
+ test.isTrue(/requires an URL/.test(ex.message));
+ test.equal(store, [0]);
+ done();
+ }
+ });
+
+ Triggers.runTriggers(triggers, null, null, null);
+});
+
+Tinytest.addAsync(
+'Triggers - runTriggers - redirect in a different event loop',
+function(test, done) {
+ var store = [];
+ var url = "http://google.com";
+ var triggers = MakeTriggers(2, store);
+ var doneCalled = false;
+
+ triggers.splice(1, 0, function(context, redirect) {
+ setTimeout(function() {
+ try {
+ redirect(url);
+ } catch(ex) {
+ test.isTrue(/sync/.test(ex.message));
+ test.equal(store, [0, 1]);
+ test.isTrue(doneCalled);
+ done();
+ }
+ }, 0);
+ });
+
+ Triggers.runTriggers(triggers, null, null, function() {
+ doneCalled = true;
+ });
+});
+
+Tinytest.addAsync(
+'Triggers - runTriggers - redirect called multiple times',
+function(test, done) {
+ var store = [];
+ var url = "http://google.com";
+ var triggers = MakeTriggers(2, store);
+ var redirectCalled = false;
+
+ triggers.splice(1, 0, function(context, redirect) {
+ redirect(url);
+ try {
+ redirect(url);
+ } catch(ex) {
+ test.isTrue(/already redirected/.test(ex.message));
+ test.equal(store, [0]);
+ test.isTrue(redirectCalled);
+ done();
+ }
+ });
+
+ Triggers.runTriggers(triggers, null, function() {
+ redirectCalled = true;
+ }, null);
+});
+
+Tinytest.addAsync(
+'Triggers - runTriggers - stop callback',
+function(test, done) {
+ var store = [];
+ var triggers = MakeTriggers(2, store);
+ triggers.splice(1, 0, function(context, redirect, stop) {
+ stop();
+ });
+
+ Triggers.runTriggers(triggers, null, null, function() {
+ store.push(2);
+ });
+
+ test.equal(store, [0]);
+ done();
+});
+
+
+Tinytest.addAsync(
+'Triggers - runTriggers - get context',
+function(test, done) {
+ var context = {};
+ var trigger = function(c) {
+ test.equal(c, context);
+ done();
+ };
+
+ Triggers.runTriggers([trigger], context, function() {}, function() {});
+});
+
+Tinytest.addAsync(
+'Triggers - createRouteBoundTriggers - matching trigger',
+function(test, done) {
+ var context = {route: {name: "abc"}};
+ var redirect = function() {};
+
+ var trigger = function(c, r) {
+ test.equal(c, context);
+ test.equal(r, redirect);
+ done();
+ };
+
+ var triggers = Triggers.createRouteBoundTriggers([trigger], ["abc"]);
+ triggers[0](context, redirect);
+});
+
+Tinytest.addAsync(
+'Triggers - createRouteBoundTriggers - multiple matching triggers',
+function(test, done) {
+ var context = {route: {name: "abc"}};
+ var redirect = function() {};
+ var doneCount = 0;
+
+ var trigger = function(c, r) {
+ test.equal(c, context);
+ test.equal(r, redirect);
+ doneCount++;
+ };
+
+ var triggers = Triggers.createRouteBoundTriggers([trigger, trigger], ["abc"]);
+ triggers[0](context, redirect);
+ triggers[1](context, redirect);
+
+ test.equal(doneCount, 2);
+ done();
+});
+
+Tinytest.addAsync(
+'Triggers - createRouteBoundTriggers - no matching trigger',
+function(test, done) {
+ var context = {route: {name: "some-other-route"}};
+ var redirect = function() {};
+ var doneCount = 0;
+
+ var trigger = function(c, r) {
+ test.equal(c, context);
+ test.equal(r, redirect);
+ doneCount++;
+ };
+
+ var triggers = Triggers.createRouteBoundTriggers([trigger], ["abc"]);
+ triggers[0](context, redirect);
+
+ test.equal(doneCount, 0);
+ done();
+});
+
+Tinytest.addAsync(
+'Triggers - createRouteBoundTriggers - negate logic',
+function(test, done) {
+ var context = {route: {name: "some-other-route"}};
+ var redirect = function() {};
+ var doneCount = 0;
+
+ var trigger = function(c, r) {
+ test.equal(c, context);
+ test.equal(r, redirect);
+ doneCount++;
+ };
+
+ var triggers = Triggers.createRouteBoundTriggers([trigger], ["abc"], true);
+ triggers[0](context, redirect);
+
+ test.equal(doneCount, 1);
+ done();
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - no filters',
+function(test, done) {
+ var original = [];
+ test.equal(Triggers.applyFilters(original), original);
+ done();
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - single trigger to array',
+function(test, done) {
+ var original = function() {};
+ test.equal(Triggers.applyFilters(original)[0], original);
+ done();
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - only and except both',
+function(test, done) {
+ var original = [];
+ try {
+ Triggers.applyFilters(original, {only: [], except: []});
+ } catch(ex) {
+ test.isTrue(/only and except/.test(ex.message));
+ done();
+ }
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - only is not an array',
+function(test, done) {
+ var original = [];
+ try {
+ Triggers.applyFilters(original, {only: "name"});
+ } catch(ex) {
+ test.isTrue(/to be an array/.test(ex.message));
+ done();
+ }
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - except is not an array',
+function(test, done) {
+ var original = [];
+ try {
+ Triggers.applyFilters(original, {except: "name"});
+ } catch(ex) {
+ test.isTrue(/to be an array/.test(ex.message));
+ done();
+ }
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - unsupported filter',
+function(test, done) {
+ var original = [];
+ try {
+ Triggers.applyFilters(original, {wowFilter: []});
+ } catch(ex) {
+ test.isTrue(/not supported/.test(ex.message));
+ done();
+ }
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - just only filter',
+function(test, done) {
+ var bounded = Triggers.applyFilters(done, {only: ["abc"]});
+ bounded[0]({route: {name: "abc"}});
+});
+
+Tinytest.addAsync(
+'Triggers - applyFilters - just except filter',
+function(test, done) {
+ var bounded = Triggers.applyFilters(done, {except: ["abc"]});
+ bounded[0]({route: {name: "some-other"}});
+});
+
+function MakeTriggers(count, store) {
+ var triggers = [];
+
+ function addTrigger(no) {
+ triggers.push(function() {
+ store.push(no);
+ });
+ }
+
+ for(var lc=0; lc<count; lc++) {
+ addTrigger(lc);
+ }
+ return triggers;
+} \ No newline at end of file
diff --git a/packages/kadira-flow-router/test/common/fast_render_route.js b/packages/kadira-flow-router/test/common/fast_render_route.js
new file mode 100644
index 00000000..d56f1c06
--- /dev/null
+++ b/packages/kadira-flow-router/test/common/fast_render_route.js
@@ -0,0 +1,48 @@
+FastRenderColl = new Mongo.Collection('fast-render-coll');
+
+FlowRouter.route('/the-fast-render-route', {
+ subscriptions: function() {
+ this.register('data', Meteor.subscribe('fast-render-data'));
+ }
+});
+
+FlowRouter.route('/the-fast-render-route-params/:id', {
+ subscriptions: function(params, queryParams) {
+ this.register('data', Meteor.subscribe('fast-render-data-params', params, queryParams));
+ }
+});
+
+FlowRouter.route('/no-fast-render', {
+ subscriptions: function() {
+ if(Meteor.isClient) {
+ this.register('data', Meteor.subscribe('fast-render-data'));
+ }
+ }
+});
+
+var frGroup = FlowRouter.group({
+ prefix: "/fr"
+});
+
+frGroup.route("/have-fr", {
+ subscriptions: function() {
+ this.register('data', Meteor.subscribe('fast-render-data'));
+ }
+});
+
+if(Meteor.isServer) {
+ if(!FastRenderColl.findOne()) {
+ FastRenderColl.insert({_id: "one", aa: 10});
+ FastRenderColl.insert({_id: "two", aa: 20});
+ }
+
+ Meteor.publish('fast-render-data', function() {
+ return FastRenderColl.find({}, {sort: {aa: -1}});
+ });
+
+ Meteor.publish('fast-render-data-params', function(params, queryParams) {
+ var fields = {params: params, queryParams: queryParams};
+ this.added('fast-render-coll', 'one', fields);
+ this.ready();
+ });
+} \ No newline at end of file
diff --git a/packages/kadira-flow-router/test/common/group.spec.js b/packages/kadira-flow-router/test/common/group.spec.js
new file mode 100644
index 00000000..e6e799cb
--- /dev/null
+++ b/packages/kadira-flow-router/test/common/group.spec.js
@@ -0,0 +1,16 @@
+Tinytest.add('Common - Group - expose group options', function (test) {
+ var pathDef = "/" + Random.id();
+ var name = Random.id();
+ var data = {aa: 10};
+ var layout = 'blah';
+
+ var group = FlowRouter.group({
+ name: name,
+ prefix: '/admin',
+ layout: layout,
+ someData: data
+ });
+
+ test.equal(group.options.someData, data);
+ test.equal(group.options.layout, layout);
+});
diff --git a/packages/kadira-flow-router/test/common/route.spec.js b/packages/kadira-flow-router/test/common/route.spec.js
new file mode 100644
index 00000000..9e4c7e5a
--- /dev/null
+++ b/packages/kadira-flow-router/test/common/route.spec.js
@@ -0,0 +1,15 @@
+Router = FlowRouter.Router;
+
+Tinytest.addAsync('Common - Route - expose route options', function (test, next) {
+ var pathDef = "/" + Random.id();
+ var name = Random.id();
+ var data = {aa: 10};
+
+ FlowRouter.route(pathDef, {
+ name: name,
+ someData: data
+ });
+
+ test.equal(FlowRouter._routesMap[name].options.someData, data);
+ next();
+});
diff --git a/packages/kadira-flow-router/test/common/router.addons.spec.js b/packages/kadira-flow-router/test/common/router.addons.spec.js
new file mode 100644
index 00000000..f5078734
--- /dev/null
+++ b/packages/kadira-flow-router/test/common/router.addons.spec.js
@@ -0,0 +1,30 @@
+Router = FlowRouter.Router;
+
+Tinytest.addAsync('Common - Addons - onRouteRegister basic usage', function (test, done) {
+ var name = Random.id();
+ var customField = Random.id();
+ var pathDef = '/' + name;
+
+ FlowRouter.onRouteRegister(function(route) {
+ test.equal(route, {
+ pathDef: pathDef,
+
+ // Route.path is deprecated and will be removed in 3.0
+ path: pathDef,
+
+ name: name,
+ options: {customField: customField}
+ });
+ FlowRouter._onRouteCallbacks = [];
+ done();
+ });
+
+ FlowRouter.route(pathDef, {
+ name: name,
+ action: function() {},
+ subscriptions: function() {},
+ triggersEnter: function() {},
+ triggersExit: function() {},
+ customField: customField
+ });
+});
diff --git a/packages/kadira-flow-router/test/common/router.path.spec.js b/packages/kadira-flow-router/test/common/router.path.spec.js
new file mode 100644
index 00000000..92f0881e
--- /dev/null
+++ b/packages/kadira-flow-router/test/common/router.path.spec.js
@@ -0,0 +1,135 @@
+Router = FlowRouter.Router;
+
+Tinytest.addAsync('Common - Router - validate path definition', function (test, next) {
+ // path must start with '/'
+ try {
+ FlowRouter.route(Random.id());
+ } catch(ex) {
+ next();
+ }
+});
+
+Tinytest.add('Common - Router - path - generic', function (test) {
+ var pathDef = "/blog/:blogId/some/:name";
+ var fields = {
+ blogId: "1001",
+ name: "superb"
+ };
+ var expectedPath = "/blog/1001/some/superb";
+
+ var path = FlowRouter.path(pathDef, fields);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - queryParams', function (test) {
+ var pathDef = "/blog/:blogId/some/:name";
+ var fields = {
+ blogId: "1001",
+ name: "superb"
+ };
+
+ var queryParams = {
+ aa: "100",
+ bb: "200"
+ };
+
+ var expectedPath = "/blog/1001/some/superb?aa=100&bb=200";
+
+ var path = FlowRouter.path(pathDef, fields, queryParams);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - just queryParams', function (test) {
+ var pathDef = "/blog/abc";
+ var queryParams = {
+ aa: "100",
+ bb: "200"
+ };
+
+ var expectedPath = "/blog/abc?aa=100&bb=200";
+
+ var path = FlowRouter.path(pathDef, null, queryParams);
+ test.equal(path, expectedPath);
+});
+
+
+Tinytest.add('Common - Router - path - missing fields', function (test) {
+ var pathDef = "/blog/:blogId/some/:name";
+ var fields = {
+ blogId: "1001",
+ };
+ var expectedPath = "/blog/1001/some";
+
+ var path = FlowRouter.path(pathDef, fields);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - no fields', function (test) {
+ var pathDef = "/blog/blogId/some/name";
+ var path = FlowRouter.path(pathDef);
+ test.equal(path, pathDef);
+});
+
+Tinytest.add('Common - Router - path - complex route', function (test) {
+ var pathDef = "/blog/:blogId/some/:name(\\d*)+";
+ var fields = {
+ blogId: "1001",
+ name: 20
+ };
+ var expectedPath = "/blog/1001/some/20";
+
+ var path = FlowRouter.path(pathDef, fields);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - optional last param missing', function (test) {
+ var pathDef = "/blog/:blogId/some/:name?";
+ var fields = {
+ blogId: "1001"
+ };
+ var expectedPath = "/blog/1001/some";
+
+ var path = FlowRouter.path(pathDef, fields);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - optional last param exists', function (test) {
+ var pathDef = "/blog/:blogId/some/:name?";
+ var fields = {
+ blogId: "1001",
+ name: 20
+ };
+ var expectedPath = "/blog/1001/some/20";
+
+ var path = FlowRouter.path(pathDef, fields);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - remove trailing slashes', function (test) {
+ var pathDef = "/blog/:blogId/some/:name//";
+ var fields = {
+ blogId: "1001",
+ name: "superb"
+ };
+ var expectedPath = "/blog/1001/some/superb";
+
+ var path = FlowRouter.path(pathDef, fields);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - handle multiple slashes', function (test) {
+ var pathDef = "/blog///some/hi////";
+ var expectedPath = "/blog/some/hi";
+
+ var path = FlowRouter.path(pathDef);
+ test.equal(path, expectedPath);
+});
+
+Tinytest.add('Common - Router - path - keep the root slash', function (test) {
+ var pathDef = "/";
+ var fields = {};
+ var expectedPath = "/";
+
+ var path = FlowRouter.path(pathDef, fields);
+ test.equal(path, expectedPath);
+});
diff --git a/packages/kadira-flow-router/test/common/router.url.spec.js b/packages/kadira-flow-router/test/common/router.url.spec.js
new file mode 100644
index 00000000..0dbf4632
--- /dev/null
+++ b/packages/kadira-flow-router/test/common/router.url.spec.js
@@ -0,0 +1,11 @@
+Tinytest.add('Common - Router - url - generic', function (test) {
+ var pathDef = "/blog/:blogId/some/:name";
+ var fields = {
+ blogId: "1001",
+ name: "superb"
+ };
+ var expectedUrl = Meteor.absoluteUrl('blog/1001/some/superb');
+
+ var path = FlowRouter.url(pathDef, fields);
+ test.equal(path, expectedUrl);
+});
diff --git a/packages/kadira-flow-router/test/server/_helpers.js b/packages/kadira-flow-router/test/server/_helpers.js
new file mode 100644
index 00000000..c7538851
--- /dev/null
+++ b/packages/kadira-flow-router/test/server/_helpers.js
@@ -0,0 +1,38 @@
+Meteor.publish('foo', function () {
+ this.ready();
+});
+
+Meteor.publish('fooNotReady', function () {
+});
+
+Meteor.publish('bar', function () {
+ this.ready();
+});
+
+// use this only to test global subs
+Meteor.publish('baz', function () {
+ this.ready();
+});
+
+Meteor.publish('bazNotReady', function () {
+});
+
+Meteor.publish('readyness', function (doIt) {
+ if(doIt) {
+ this.ready();
+ }
+});
+
+InjectData = Package['meteorhacks:inject-data'].InjectData;
+var urlResolve = Npm.require('url').resolve;
+GetFRData = function GetFRData(path) {
+ var url = urlResolve(process.env.ROOT_URL, path);
+ // FastRender only servers if there is a accept header with html in it
+ var options = {
+ headers: {'accept': 'html'}
+ };
+ var res = HTTP.get(url, options);
+
+ var encodedData = res.content.match(/data">(.*)<\/script/)[1];
+ return InjectData._decode(encodedData)['fast-render-data'];
+} \ No newline at end of file
diff --git a/packages/kadira-flow-router/test/server/plugins/fast_render.js b/packages/kadira-flow-router/test/server/plugins/fast_render.js
new file mode 100644
index 00000000..1ec77866
--- /dev/null
+++ b/packages/kadira-flow-router/test/server/plugins/fast_render.js
@@ -0,0 +1,35 @@
+Tinytest.add('Server - Fast Render - fast render supported route', function (test) {
+ var expectedFastRenderCollData = [
+ [{_id: "two", aa: 20}, {_id: "one", aa: 10}]
+ ];
+
+ var data = GetFRData('/the-fast-render-route');
+ test.equal(data.collectionData['fast-render-coll'], expectedFastRenderCollData);
+});
+
+Tinytest.add('Server - Fast Render - fast render supported route with params', function (test) {
+ var expectedFastRenderCollData = [
+ [{
+ _id: "one",
+ params: {id: 'the-id'},
+ queryParams: {aa: "20"}
+ }]
+ ];
+
+ var data = GetFRData('/the-fast-render-route-params/the-id?aa=20');
+ test.equal(data.collectionData['fast-render-coll'], expectedFastRenderCollData);
+});
+
+Tinytest.add('Server - Fast Render - no fast render supported route', function (test) {
+ var data = GetFRData('/no-fast-render');
+ test.equal(data.collectionData, {});
+});
+
+Tinytest.add('Server - Fast Render - with group routes', function (test) {
+ var expectedFastRenderCollData = [
+ [{_id: "two", aa: 20}, {_id: "one", aa: 10}]
+ ];
+
+ var data = GetFRData('/fr/have-fr');
+ test.equal(data.collectionData['fast-render-coll'], expectedFastRenderCollData);
+}); \ No newline at end of file