summaryrefslogtreecommitdiffstats
path: root/packages/kadira-flow-router/test/client
diff options
context:
space:
mode:
Diffstat (limited to 'packages/kadira-flow-router/test/client')
-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
9 files changed, 2230 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