<commit_before>"use strict";

//Load dependencies
var async = require("async");
var applicationStorage = process.require("core/applicationStorage.js");
var updateModel = process.require("updates/updateModel.js");
var updateService = process.require("updates/updateService.js");
var guildProgressModel = process.require("guildProgress/guildProgressModel.js");
var killModel = process.require("kills/killModel.js");
var rankModel = process.require("ranks/rankModel.js");
var realmModel = process.require("realms/realmModel.js");
var bnetAPI = process.require("core/api/bnet.js");

/**
 * ProgressUpdateProcess constructor
 * @constructor
 */
function ProgressUpdateProcess() {
}

/**
 * Update Guild progress
 */
ProgressUpdateProcess.prototype.updateGuildProgress = function () {
    var logger = applicationStorage.logger;
    var config = applicationStorage.config;
    var self = this;
    async.waterfall([
            function (callback) {
                //Get next guild to update
                updateService.getNextUpdate('wp_pu', function (error, guildProgress) {
                    if (guildProgress == null) {
                        //Guild update is empty
                        logger.info("No guild progress to update ... waiting 3 sec");
                        setTimeout(function () {
                            callback(true);
                        }, 3000);
                    } else {
                        logger.info("Update guild process %s-%s-%s", guildProgress.region, guildProgress.realm, guildProgress.name);
                        callback(error, guildProgress);
                    }
                });
            },
            function (guildProgress, callback) {
                async.eachSeries(config.progress.raids, function (raid, callback) {
                    async.waterfall([
                            function (callback) {
                                killModel.computeProgress(guildProgress.region, guildProgress.realm, guildProgress.name, raid.tier, function (error, result) {
                                    callback(error, result);
                                });
                            },
                            function (result, callback) {
                                var progress = {};
                                var bestNormalKillTimestamp = 0;
                                var bestHeroicKillTimestamp = 0;
                                var bestMythicKillTimestamp = 0;

                                async.forEachSeries(result, function (obj, callback) {

                                    logger.verbose("Kills found for %s-%s R:(%s) I:(%s)", obj._id.boss, obj._id.difficulty, obj.value.timestamps.join(','), obj.value.irrelevantTimestamps.join(','))

                                    if (!progress[obj._id.difficulty]) {
                                        progress[obj._id.difficulty] = {};
                                    }
                                    progress[obj._id.difficulty][obj._id.boss] = obj.value;

                                    if (!progress[obj._id.difficulty + "Count"]) {
                                        progress[obj._id.difficulty + "Count"] = 0;
                                    }

                                    if (obj.value.timestamps.length > 0) {
                                        progress[obj._id.difficulty + "Count"]++;
                                        if (obj._id.difficulty == "normal") {
                                            if (obj.value.timestamps[0][0] > bestNormalKillTimestamp) {
                                                bestNormalKillTimestamp = obj.value.timestamps[0][0];
                                            }
                                        } else if (obj._id.difficulty == "heroic") {
                                            if (obj.value.timestamps[0][0] > bestHeroicKillTimestamp) {
                                                bestHeroicKillTimestamp = obj.value.timestamps[0][0];
                                            }
                                        } else {
                                            if (obj.value.timestamps[0][0] > bestMythicKillTimestamp) {
                                                bestMythicKillTimestamp = obj.value.timestamps[0][0];
                                            }
                                        }
                                    }

                                    callback();
                                }, function () {
                                    var obj = {};
                                    if (bestMythicKillTimestamp != 0) {
                                        progress.bestKillTimestamp = bestMythicKillTimestamp;
                                    } else if (bestHeroicKillTimestamp != 0) {
                                        progress.bestKillTimestamp = bestHeroicKillTimestamp;
                                    } else if (bestNormalKillTimestamp != 0) {
                                        progress.bestKillTimestamp = bestNormalKillTimestamp;
                                    }

                                    progress.updated = new Date().getTime();
                                    obj["tier_" + raid.tier] = progress;

                                    guildProgressModel.upsert(guildProgress.region, guildProgress.realm, guildProgress.name, {progress: obj}, function (error) {
                                        logger.verbose("Update Progress for guild %s-%s-%s", guildProgress.region, guildProgress.realm, guildProgress.name);
                                        callback(error, progress);
                                    });

                                });
                            }, function (progress, callback) {
                                if (progress.bestKillTimestamp) {
                                    logger.verbose("Update Score for guild %s-%s-%s", guildProgress.region, guildProgress.realm, guildProgress.name);

                                    var preScore = 0;
                                    if (progress.normalCount && progress.normalCount > 0) {
                                        preScore = progress.normalCount;
                                    }
                                    if (progress.heroicCount && progress.heroicCount > 0) {
                                        preScore = progress.heroicCount * 100;
                                    }
                                    if (progress.mythicCount && progress.mythicCount > 0) {
                                        preScore = progress.mythicCount * 10000;
                                    }
                                    //Calculate the score for redis bestTimestamp - 2Years * score
                                    var score = parseInt(progress.bestKillTimestamp / 1000, 10) - (3600 * 24 * 365 * 2 * preScore);

                                    async.parallel([
                                        function (callback) {
                                            rankModel.upsert(raid.tier, guildProgress.region, guildProgress.realm, guildProgress.name, score, function (error) {
                                                callback(error);
                                            });
                                        },
                                        function (callback) {
                                            rankModel.upsert(raid.tier + "_" + guildProgress.region, guildProgress.region, guildProgress.realm, guildProgress.name, score, function (error) {
                                                callback(error);
                                            });
                                        },
                                        function (callback) {
                                            realmModel.findOne({
                                                region: guildProgress.region,
                                                name: guildProgress.realm
                                            }, {connected_realms: 1}, function (error, realm) {
                                                if (realm) {
                                                    rankModel.upsert(raid.tier + "_" + guildProgress.region + "_" + realm.connected_realms.join('_'), guildProgress.region, guildProgress.realm, guildProgress.name, score, function (error) {
                                                        callback(error);
                                                    });
                                                } else {
                                                    logger.warn("Realm %s-%s not found", guildProgress.region, guildProgress.realm);
                                                    callback(error);
                                                }
                                            });
                                        }
                                    ], function (error) {
                                        callback(error);
                                    });

                                } else {
                                    callback();
                                }
                            }
                        ],
                        function (error) {
                            callback(error);
                        }
                    )
                }, function (error) {
                    callback(error);
                });
            }
        ],
        function (error) {
            if (error && error !== true) {
                logger.error(error.message);
            }
            self.updateGuildProgress();

        }
    )
    ;
}
;

/**
 * Start ProgressUpdateProcess
 * @param callback
 */
ProgressUpdateProcess.prototype.start = function (callback) {
    applicationStorage.logger.info("Starting ProgressUpdateProcess");
    this.updateGuildProgress();
    callback();

};

module.exports = ProgressUpdateProcess;<commit_msg>Display a normalCount, heroicCount and mythicCount on all progress.<commit_after>"use strict";

//Load dependencies
var async = require("async");
var applicationStorage = process.require("core/applicationStorage.js");
var updateModel = process.require("updates/updateModel.js");
var updateService = process.require("updates/updateService.js");
var guildProgressModel = process.require("guildProgress/guildProgressModel.js");
var killModel = process.require("kills/killModel.js");
var rankModel = process.require("ranks/rankModel.js");
var realmModel = process.require("realms/realmModel.js");
var bnetAPI = process.require("core/api/bnet.js");

/**
 * ProgressUpdateProcess constructor
 * @constructor
 */
function ProgressUpdateProcess() {
}

/**
 * Update Guild progress
 */
ProgressUpdateProcess.prototype.updateGuildProgress = function () {
    var logger = applicationStorage.logger;
    var config = applicationStorage.config;
    var self = this;
    async.waterfall([
            function (callback) {
                //Get next guild to update
                updateService.getNextUpdate('wp_pu', function (error, guildProgress) {
                    if (guildProgress == null) {
                        //Guild update is empty
                        logger.info("No guild progress to update ... waiting 3 sec");
                        setTimeout(function () {
                            callback(true);
                        }, 3000);
                    } else {
                        logger.info("Update guild process %s-%s-%s", guildProgress.region, guildProgress.realm, guildProgress.name);
                        callback(error, guildProgress);
                    }
                });
            },
            function (guildProgress, callback) {
                async.eachSeries(config.progress.raids, function (raid, callback) {
                    async.waterfall([
                            function (callback) {
                                killModel.computeProgress(guildProgress.region, guildProgress.realm, guildProgress.name, raid.tier, function (error, result) {
                                    callback(error, result);
                                });
                            },
                            function (result, callback) {
                                var progress = {normalCount:0,heroicCount:0,mythicCount:0};
                                var bestNormalKillTimestamp = 0;
                                var bestHeroicKillTimestamp = 0;
                                var bestMythicKillTimestamp = 0;

                                async.forEachSeries(result, function (obj, callback) {

                                    logger.verbose("Kills found for %s-%s R:(%s) I:(%s)", obj._id.boss, obj._id.difficulty, obj.value.timestamps.join(','), obj.value.irrelevantTimestamps.join(','))

                                    if (!progress[obj._id.difficulty]) {
                                        progress[obj._id.difficulty] = {};
                                    }
                                    progress[obj._id.difficulty][obj._id.boss] = obj.value;

                                    if (!progress[obj._id.difficulty + "Count"]) {
                                        progress[obj._id.difficulty + "Count"] = 0;
                                    }

                                    if (obj.value.timestamps.length > 0) {
                                        progress[obj._id.difficulty + "Count"]++;
                                        if (obj._id.difficulty == "normal") {
                                            if (obj.value.timestamps[0][0] > bestNormalKillTimestamp) {
                                                bestNormalKillTimestamp = obj.value.timestamps[0][0];
                                            }
                                        } else if (obj._id.difficulty == "heroic") {
                                            if (obj.value.timestamps[0][0] > bestHeroicKillTimestamp) {
                                                bestHeroicKillTimestamp = obj.value.timestamps[0][0];
                                            }
                                        } else {
                                            if (obj.value.timestamps[0][0] > bestMythicKillTimestamp) {
                                                bestMythicKillTimestamp = obj.value.timestamps[0][0];
                                            }
                                        }
                                    }

                                    callback();
                                }, function () {
                                    var obj = {};
                                    if (bestMythicKillTimestamp != 0) {
                                        progress.bestKillTimestamp = bestMythicKillTimestamp;
                                    } else if (bestHeroicKillTimestamp != 0) {
                                        progress.bestKillTimestamp = bestHeroicKillTimestamp;
                                    } else if (bestNormalKillTimestamp != 0) {
                                        progress.bestKillTimestamp = bestNormalKillTimestamp;
                                    }

                                    progress.updated = new Date().getTime();
                                    obj["tier_" + raid.tier] = progress;

                                    guildProgressModel.upsert(guildProgress.region, guildProgress.realm, guildProgress.name, {progress: obj}, function (error) {
                                        logger.verbose("Update Progress for guild %s-%s-%s", guildProgress.region, guildProgress.realm, guildProgress.name);
                                        callback(error, progress);
                                    });

                                });
                            }, function (progress, callback) {
                                if (progress.bestKillTimestamp) {
                                    logger.verbose("Update Score for guild %s-%s-%s", guildProgress.region, guildProgress.realm, guildProgress.name);

                                    var preScore = 0;
                                    if (progress.normalCount && progress.normalCount > 0) {
                                        preScore = progress.normalCount;
                                    }
                                    if (progress.heroicCount && progress.heroicCount > 0) {
                                        preScore = progress.heroicCount * 100;
                                    }
                                    if (progress.mythicCount && progress.mythicCount > 0) {
                                        preScore = progress.mythicCount * 10000;
                                    }
                                    //Calculate the score for redis bestTimestamp - 2Years * score
                                    var score = parseInt(progress.bestKillTimestamp / 1000, 10) - (3600 * 24 * 365 * 2 * preScore);

                                    async.parallel([
                                        function (callback) {
                                            rankModel.upsert(raid.tier, guildProgress.region, guildProgress.realm, guildProgress.name, score, function (error) {
                                                callback(error);
                                            });
                                        },
                                        function (callback) {
                                            rankModel.upsert(raid.tier + "_" + guildProgress.region, guildProgress.region, guildProgress.realm, guildProgress.name, score, function (error) {
                                                callback(error);
                                            });
                                        },
                                        function (callback) {
                                            realmModel.findOne({
                                                region: guildProgress.region,
                                                name: guildProgress.realm
                                            }, {connected_realms: 1}, function (error, realm) {
                                                if (realm) {
                                                    rankModel.upsert(raid.tier + "_" + guildProgress.region + "_" + realm.connected_realms.join('_'), guildProgress.region, guildProgress.realm, guildProgress.name, score, function (error) {
                                                        callback(error);
                                                    });
                                                } else {
                                                    logger.warn("Realm %s-%s not found", guildProgress.region, guildProgress.realm);
                                                    callback(error);
                                                }
                                            });
                                        }
                                    ], function (error) {
                                        callback(error);
                                    });

                                } else {
                                    callback();
                                }
                            }
                        ],
                        function (error) {
                            callback(error);
                        }
                    )
                }, function (error) {
                    callback(error);
                });
            }
        ],
        function (error) {
            if (error && error !== true) {
                logger.error(error.message);
            }
            self.updateGuildProgress();

        }
    )
    ;
}
;

/**
 * Start ProgressUpdateProcess
 * @param callback
 */
ProgressUpdateProcess.prototype.start = function (callback) {
    applicationStorage.logger.info("Starting ProgressUpdateProcess");
    this.updateGuildProgress();
    callback();

};

module.exports = ProgressUpdateProcess;<|endoftext|>


<commit_before>/**
 * @venus-library jasmine
 * @venus-include ../../../../../moment/moment.js
 * @venus-include ../../../../src/functions.js
 * @venus-include ../../../../src/Lib/Logger/Handler/Interface.js
 * @venus-include ../../../../src/Lib/Logger/Interface.js
 * @venus-code ../../../../src/Lib/Logger/Handler/Console.js
 */

describe('console logger handler', function () {

    it('should not handle', function () {

        var handler = new Sy.Lib.Logger.Handler.Console('info');

        expect(handler.isHandling('error')).toBe(false);

    });

    it('should handle the level defined', function () {

        var handler = new Sy.Lib.Logger.Handler.Console('info');

        expect(handler.isHandling('info')).toBe(true);

    });

    it('should return itself', function () {

        var handler = new Sy.Lib.Logger.Handler.Console('info');

        expect(handler.handle('info', 'foo')).toEqual(handler);

    });

});<commit_msg>fix console logger handler UT<commit_after>/**
 * @venus-library jasmine
 * @venus-include ../../../../vendor/moment/moment.js
 * @venus-include ../../../../src/functions.js
 * @venus-include ../../../../src/Lib/Logger/Handler/Interface.js
 * @venus-include ../../../../src/Lib/Logger/Interface.js
 * @venus-code ../../../../src/Lib/Logger/Handler/Console.js
 */

describe('console logger handler', function () {

    it('should not handle', function () {

        var handler = new Sy.Lib.Logger.Handler.Console('info');

        expect(handler.isHandling('error')).toBe(false);

    });

    it('should handle the level defined', function () {

        var handler = new Sy.Lib.Logger.Handler.Console('info');

        expect(handler.isHandling('info')).toBe(true);
        expect(handler.isHandling('foo')).toBe(false);

    });

    it('should return itself', function () {

        var handler = new Sy.Lib.Logger.Handler.Console('info');

        expect(handler.handle('name', 'info', 'foo')).toEqual(handler);

    });

    it('should return say that the level does not exist', function () {

        expect(function () {
            var handler = new Sy.Lib.Logger.Handler.Console('foo');
        }).toThrow('Unknown logger level');

    });

});<|endoftext|>


<commit_before>var assert = require('./assert'),
    dot = require('graphlib-dot'),
    layout = require('..').layout,
    path = require('path'),
    fs = require('fs');

describe('smoke tests', function() {
  var smokeDir = path.join(__dirname, 'smoke');
  var fileNames = fs.readdirSync(smokeDir)
                    .filter(function(x) { return x.slice(-4) === '.dot'; })
                    .map(function(x) { return path.join(smokeDir, x); });
  fileNames.forEach(function(fileName) {
    var file = fs.readFileSync(fileName, { encoding: 'utf-8' }),
        g = dot.parse(file);

    describe('layout for ' + fileName, function() {
      it('only includes nodes in the input graph', function() {
        var nodes = g.nodes();
        assert.sameMembers(layout().run(g).nodes(), nodes);
      });

      it('only includes edges in the input graph', function() {
        var edges = g.edges();
        assert.sameMembers(layout().run(g).edges(), edges);
      });

      it('has the same incident nodes for each edge', function() {
        function incidentNodes(g) {
          var edges = {};
          g.edges().forEach(function(e) {
            edges[e] = g.incidentNodes(e);
          });
          return edges;
        }

        var edges = incidentNodes(g);
        assert.deepEqual(incidentNodes(layout().run(g)), edges);
      });

      it('has valid control points for each edge', function() {
        layout().run(g).eachEdge(function(e, u, v, value) {
          assert.property(value, 'points');
          value.points.forEach(function(p) {
            assert.property(p, 'x');
            assert.property(p, 'y');
            assert.isFalse(Number.isNaN(p.x));
            assert.isFalse(Number.isNaN(p.y));
          });
        });
      });

      it('respects rankSep', function() {
        // For each edge we check that the difference between the y value for
        // incident nodes is equal to or greater than ranksep. We make an
        // exception for self edges.

        var sep = 50;
        var out = layout().rankSep(sep).run(g);

        out.eachEdge(function(e, u, v) {
            if (u !== v) {
              var uY = out.node(u).y,
                  vY = out.node(v).y,
                  uHeight = Number(out.node(u).height),
                  vHeight = Number(out.node(v).height),
                  actualSep = Math.abs(vY - uY) - (uHeight + vHeight) / 2;
              assert.isTrue(actualSep >= sep,
                            'Distance between ' + u + ' and ' + v + ' should be ' + sep +
                            ' but was ' + actualSep);
            }
          });
      });

      it('has valid dimensions', function() {
        var bbox = layout().run(g).graph().bbox;
        assert.property(bbox, 'width');
        assert.property(bbox, 'height');
        assert.isFalse(Number.isNaN(bbox.width));
        assert.isFalse(Number.isNaN(bbox.height));
      });
    });
  });
});
<commit_msg>Change encoding for smoke graphs to UTF-8<commit_after>var assert = require('./assert'),
    dot = require('graphlib-dot'),
    layout = require('..').layout,
    path = require('path'),
    fs = require('fs');

describe('smoke tests', function() {
  var smokeDir = path.join(__dirname, 'smoke');
  var fileNames = fs.readdirSync(smokeDir)
                    .filter(function(x) { return x.slice(-4) === '.dot'; })
                    .map(function(x) { return path.join(smokeDir, x); });
  fileNames.forEach(function(fileName) {
    var file = fs.readFileSync(fileName, { encoding: 'UTF-8' }),
        g = dot.parse(file);

    describe('layout for ' + fileName, function() {
      it('only includes nodes in the input graph', function() {
        var nodes = g.nodes();
        assert.sameMembers(layout().run(g).nodes(), nodes);
      });

      it('only includes edges in the input graph', function() {
        var edges = g.edges();
        assert.sameMembers(layout().run(g).edges(), edges);
      });

      it('has the same incident nodes for each edge', function() {
        function incidentNodes(g) {
          var edges = {};
          g.edges().forEach(function(e) {
            edges[e] = g.incidentNodes(e);
          });
          return edges;
        }

        var edges = incidentNodes(g);
        assert.deepEqual(incidentNodes(layout().run(g)), edges);
      });

      it('has valid control points for each edge', function() {
        layout().run(g).eachEdge(function(e, u, v, value) {
          assert.property(value, 'points');
          value.points.forEach(function(p) {
            assert.property(p, 'x');
            assert.property(p, 'y');
            assert.isFalse(Number.isNaN(p.x));
            assert.isFalse(Number.isNaN(p.y));
          });
        });
      });

      it('respects rankSep', function() {
        // For each edge we check that the difference between the y value for
        // incident nodes is equal to or greater than ranksep. We make an
        // exception for self edges.

        var sep = 50;
        var out = layout().rankSep(sep).run(g);

        out.eachEdge(function(e, u, v) {
            if (u !== v) {
              var uY = out.node(u).y,
                  vY = out.node(v).y,
                  uHeight = Number(out.node(u).height),
                  vHeight = Number(out.node(v).height),
                  actualSep = Math.abs(vY - uY) - (uHeight + vHeight) / 2;
              assert.isTrue(actualSep >= sep,
                            'Distance between ' + u + ' and ' + v + ' should be ' + sep +
                            ' but was ' + actualSep);
            }
          });
      });

      it('has valid dimensions', function() {
        var bbox = layout().run(g).graph().bbox;
        assert.property(bbox, 'width');
        assert.property(bbox, 'height');
        assert.isFalse(Number.isNaN(bbox.width));
        assert.isFalse(Number.isNaN(bbox.height));
      });
    });
  });
});
<|endoftext|>


<commit_before>module.exports = function(server){

  var Dropbox = require('dropbox'),
      events = require('events'),
      eventEmitter = new events.EventEmitter(),
      config = require('../../../config'),
      callbackUrl = 'https://' + config.host + '/auth/callback',
      requireSSL = require('../../authHandler').requireSSL,
      User = require('../../models/user'),
      Subscription = require('../../models/subscription'),
      logger = require('../../helper').logger;

  var errorMessage = {
    NO_ACCOUNT: 'You need a Blot account to log in'
  };

  server.get('/auth', requireSSL, function (request, response) {

    // If the user is already authenticated then
    // avoid repeating the auth process and
    if (request.session.uid) {
      var afterAuth = request.session.afterAuth;
      delete request.session.afterAuth;
      return response.redirect(afterAuth || '/');
    }

    var _session = {};

    // Cache the current session so we can
    // link a newly authenticated user to
    // someone who just bought an account.
    for (var i in request.session)
      _session[i] = request.session[i];

    // Get a fresh session ID to use during auth
    request.session.regenerate(function(error){

      if (error) throw error;

      // Replace the old session content
      for (var j in _session)
        request.session[j] = _session[j];

      var client = new Dropbox.Client(config.dropbox),
          sessionID = request.sessionID;

      // Register a new authDriver. We pass the request &
      // response so we can redirect the user to Dropbox.
      client.authDriver(new authDriver(request, response));

      // Start the authentication flow.
      client.authenticate(function(error, client){

        // This function is invoked when the user returns
        // to /auth/callback and so we pass the client
        eventEmitter.emit(clientReady(sessionID), error, client);
      });
    });
  });

  server.get('/auth/callback', requireSSL, function (request, response) {

    var code = request.query.code,
        error = request.query.error;

    if (error) return response.redirect(connectError(error));

    if (!code) return response.redirect('/auth');

    var subscription = request.session.subscription,
        email = request.session.email,
        isNewUser = !!(subscription && email),
        sessionID = request.sessionID;

    var afterAuth = request.session.afterAuth;
        delete request.session.afterAuth;

    // Tell auth driver to try and create an OAuth token
    eventEmitter.emit(backFromDropbox(sessionID), {code: code});

    // Once the auth driver has attempted to create a
    // client this function will be called.
    eventEmitter.once(clientReady(sessionID), function(error, client){

      if (error || !client.isAuthenticated())
        return response.redirect(connectError(error));

      var uid = client.dropboxUid();

      // Check if the user has registered with Blot
      User.getBy({uid: uid}, function(err, existingUser){

        if (err) throw err;

        // Disabled users have chosen to be so
        // this will happen to users who have not paid too
        // The user is NOT authenticated
        if (existingUser && existingUser.isDisabled)
          return response.redirect('/disabled');

        // Catch users without a Blot account
        if (!isNewUser && !existingUser) {
          logger(uid, errorMessage.NO_ACCOUNT);
          return response.redirect(formError(errorMessage.NO_ACCOUNT));
        }

        // Authenticate the user
        request.session.uid = uid;

        // And store their blog if possible
        if (existingUser) {
          request.session.blogID = existingUser.lastSession;
        }

        if (isNewUser) {

          // Ensure the user's stripe subscription info is connected
          // to their Dropbox (and Blot) account UID
          Subscription.bind(subscription.customer, uid, function(){

            User.create(client, email, subscription, function(error, status){

              if (subscription.customer === 'false') {
                logger('Created free user successfully with email ' + email);
              }

              // Make sure the information about
              // the charge doesn't persist to confuse
              // other routes or this route if re-login
              delete request.session.email;
              delete request.session.subscription;

              response.redirect('/create-blog');
            });
          });
        }

        else if (existingUser) {

          response.redirect(afterAuth || '/');

          User.update(client, function(error, status){

            if (error) logger(null, error);
          });
        }
      });
    });
  });

  function authDriver (request, response) {

    return {

      authType: function() {return 'code';},

      url: function() {return callbackUrl;},

      doAuthorize: function(authUrl, state, client, callback) {

        var sessionID = request.sessionID;

        // This event is emitted when the user hits /auth/callback
        // and will tell the Dropbox client to proceed with auth
        eventEmitter.once(backFromDropbox(sessionID), callback);

        // Redirect the user to Dropbox.com to click 'authorize'
        response.redirect(authUrl);
      }
    };
  }

  function clientReady (sessionID) {
    return 'clientReady:' + sessionID;
  }

  function backFromDropbox (sessionID) {
    return 'hasReturned:' + sessionID;
  }

  function connectError (message) {
    return '/connect?error=' + encodeURIComponent(message);
  }

  function formError (message) {
    return '/sign-up?error=' + encodeURIComponent(message);
  }
};<commit_msg>remove unused variable<commit_after>module.exports = function(server){

  var Dropbox = require('dropbox'),
      events = require('events'),
      eventEmitter = new events.EventEmitter(),
      config = require('../../../config'),
      callbackUrl = 'https://' + config.host + '/auth/callback',
      requireSSL = require('../../authHandler').requireSSL,
      User = require('../../models/user'),
      Subscription = require('../../models/subscription'),
      logger = require('../../helper').logger;

  var errorMessage = {
    NO_ACCOUNT: 'You need a Blot account to log in'
  };

  server.get('/auth', requireSSL, function (request, response) {

    // If the user is already authenticated then
    // avoid repeating the auth process and
    if (request.session.uid) {
      var afterAuth = request.session.afterAuth;
      delete request.session.afterAuth;
      return response.redirect(afterAuth || '/');
    }

    var _session = {};

    // Cache the current session so we can
    // link a newly authenticated user to
    // someone who just bought an account.
    for (var i in request.session)
      _session[i] = request.session[i];

    // Get a fresh session ID to use during auth
    request.session.regenerate(function(error){

      if (error) throw error;

      // Replace the old session content
      for (var j in _session)
        request.session[j] = _session[j];

      var client = new Dropbox.Client(config.dropbox),
          sessionID = request.sessionID;

      // Register a new authDriver. We pass the request &
      // response so we can redirect the user to Dropbox.
      client.authDriver(new authDriver(request, response));

      // Start the authentication flow.
      client.authenticate(function(error, client){

        // This function is invoked when the user returns
        // to /auth/callback and so we pass the client
        eventEmitter.emit(clientReady(sessionID), error, client);
      });
    });
  });

  server.get('/auth/callback', requireSSL, function (request, response) {

    var code = request.query.code,
        error = request.query.error;

    if (error) return response.redirect(connectError(error));

    if (!code) return response.redirect('/auth');

    var subscription = request.session.subscription,
        email = request.session.email,
        isNewUser = !!(subscription && email),
        sessionID = request.sessionID;

    var afterAuth = request.session.afterAuth;
        delete request.session.afterAuth;

    // Tell auth driver to try and create an OAuth token
    eventEmitter.emit(backFromDropbox(sessionID), {code: code});

    // Once the auth driver has attempted to create a
    // client this function will be called.
    eventEmitter.once(clientReady(sessionID), function(error, client){

      if (error || !client.isAuthenticated())
        return response.redirect(connectError(error));

      var uid = client.dropboxUid();

      // Check if the user has registered with Blot
      User.getBy({uid: uid}, function(err, existingUser){

        if (err) throw err;

        // Disabled users have chosen to be so
        // this will happen to users who have not paid too
        // The user is NOT authenticated
        if (existingUser && existingUser.isDisabled)
          return response.redirect('/disabled');

        // Catch users without a Blot account
        if (!isNewUser && !existingUser) {
          logger(uid, errorMessage.NO_ACCOUNT);
          return response.redirect(formError(errorMessage.NO_ACCOUNT));
        }

        // Authenticate the user
        request.session.uid = uid;

        // And store their blog if possible
        if (existingUser) {
          request.session.blogID = existingUser.lastSession;
        }

        if (isNewUser) {

          // Ensure the user's stripe subscription info is connected
          // to their Dropbox (and Blot) account UID
          Subscription.bind(subscription.customer, uid, function(){

            User.create(client, email, subscription, function(error){

              if (error) return next(error);

              if (subscription.customer === 'false') {
                logger('Created free user successfully with email ' + email);
              }

              // Make sure the information about
              // the charge doesn't persist to confuse
              // other routes or this route if re-login
              delete request.session.email;
              delete request.session.subscription;

              response.redirect('/create-blog');
            });
          });
        }

        else if (existingUser) {

          response.redirect(afterAuth || '/');

          User.update(client, function(error){

            if (error) logger(null, error);
          });
        }
      });
    });
  });

  function authDriver (request, response) {

    return {

      authType: function() {return 'code';},

      url: function() {return callbackUrl;},

      doAuthorize: function(authUrl, state, client, callback) {

        var sessionID = request.sessionID;

        // This event is emitted when the user hits /auth/callback
        // and will tell the Dropbox client to proceed with auth
        eventEmitter.once(backFromDropbox(sessionID), callback);

        // Redirect the user to Dropbox.com to click 'authorize'
        response.redirect(authUrl);
      }
    };
  }

  function clientReady (sessionID) {
    return 'clientReady:' + sessionID;
  }

  function backFromDropbox (sessionID) {
    return 'hasReturned:' + sessionID;
  }

  function connectError (message) {
    return '/connect?error=' + encodeURIComponent(message);
  }

  function formError (message) {
    return '/sign-up?error=' + encodeURIComponent(message);
  }
};<|endoftext|>


<commit_before>#! /usr/bin/env node
const shell = require('shelljs');
const chalk = require('chalk');
// SET SILENT TRUE SO THAT DEFAULT OUTPUT IS NOT PRINTED ON CONSOLE
shell.config.silent = true;
// get command line argument for commit message
module.exports = (branchName, args, callback) => {
  // remove \n from the end
  let command = 'git push';
  switch (args.length) {
    case 0:
      command += ` origin ${branchName}`;
      break;
    case 1:
      command += ` origin ${args[0]}`;
      break;
    case 2:
      command += ` ${args[0]} ${args[1]}`;
      break;
    default:
      callback(chalk.redBright('Invalid arguments'));
      return;
  }
  shell.exec(command, (code, stdout, stderr) => {
    // console.log(121, { code, stdout, stderr });
    if (stderr) {
      console.log(2);
      const commitLine = stderr.substr(stderr.indexOf('\n   '));
      console.log(commitLine);
      callback(chalk.redBright(stderr));
      return;
    }
    callback(chalk.greenBright(stdout));
  });
};
<commit_msg>invalid arg removed from data<commit_after>#! /usr/bin/env node
const shell = require('shelljs');
const chalk = require('chalk');
// SET SILENT TRUE SO THAT DEFAULT OUTPUT IS NOT PRINTED ON CONSOLE
shell.config.silent = true;
// get command line argument for commit message
module.exports = (branchName, args, callback) => {
  // remove \n from the end
  let command = 'git push';
  switch (args.length) {
    case 0:
      command += ` origin ${branchName}`;
      break;
    case 1:
      command += ` origin ${args[0]}`;
      break;
    case 2:
      command += ` ${args[0]} ${args[1]}`;
      break;
    default:
      callback(chalk.redBright('Invalid arguments'));
      return;
  }
  shell.exec(command, (code, stdout, stderr) => {
    // console.log(121, { code, stdout, stderr });
    if (stderr) {
      console.log(2);
      const commitLine = stderr.substr(stderr.indexOf('\n   '));
      console.log({ commitLine });
      callback(chalk.redBright(stderr));
      return;
    }
    callback(chalk.greenBright(stdout));
  });
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
  Update Pebble Watch information

  Copyright (c) 2015 OpenAPS Contributors

  Released under MIT license. See the accompanying LICENSE.txt file for
  full terms and conditions

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

*/

function getTime(minutes) {
    var baseTime = new Date();
    baseTime.setHours('00');
    baseTime.setMinutes('00');
    baseTime.setSeconds('00');

    return baseTime.getTime() + minutes * 60 * 1000;

}

/* Return basal rate(U / hr) at the provided timeOfDay */

function basalLookup() {
    var now = new Date();
    basalRate = Math.round(basalprofile_data[basalprofile_data.length-1].rate*100)/100

    for (var i = 0; i < basalprofile_data.length - 1; i++) {
        if ((now >= getTime(basalprofile_data[i].minutes)) && (now < getTime(basalprofile_data[i + 1].minutes))) {
            basalRate = basalprofile_data[i].rate.toFixed(2);
            break;
        }
    }
}

function fileHM(file) {
    var filedate = new Date(fs.statSync(file).mtime);
    var HMS = filedate.toLocaleTimeString().split(":")
    return HMS[0].concat(":", HMS[1]);
}

if (!module.parent) {

    var fs = require('fs');

    var glucose_input = process.argv.slice(2, 3).pop()
    var iob_input = process.argv.slice(3, 4).pop()
    var basalprofile_input = process.argv.slice(4, 5).pop()
    var currenttemp_input = process.argv.slice(5, 6).pop()
    var requestedtemp_input = process.argv.slice(6, 7).pop()
    var enactedtemp_input = process.argv.slice(7, 8).pop()
    var meal_input = process.argv.slice(8, 9).pop()

    if (!glucose_input || !iob_input || !basalprofile_input || !currenttemp_input || !requestedtemp_input || !enactedtemp_input) {
        console.log('usage: ', process.argv.slice(0, 2), '<glucose.json> <iob.json> <current_basal_profile.json> <currenttemp.json> <requestedtemp.json> <enactedtemp.json> [meal.json]');
        process.exit(1);
    }

    var cwd = process.cwd()
    var file = cwd + '/' + glucose_input;
    var glucose_data = require(file);
    var bgTime = fileHM(file);
    if (glucose_data[0].dateString) {
        var bgDate = new Date(glucose_data[0].dateString);
        var HMS = bgDate.toLocaleTimeString().split(":")
        bgTime = HMS[0].concat(":", HMS[1]);
    }

    var bgnow = glucose_data[0].glucose;
    var iob_data = require(cwd + '/' + iob_input);
    iob = iob_data.iob.toFixed(1);
    var basalprofile_data = require(cwd + '/' + basalprofile_input);
    var basalRate;
    basalLookup();
    file = cwd + '/' + currenttemp_input;
    var temp = require(file);
    var temp_time = fileHM(file);
    var tempstring;
    if (temp.duration < 1) {
        tempstring = "No temp basal";
    } else {
        tempstring = "Tmp: " + temp.duration + "m@" + temp.rate.toFixed(1);
    }
    try {
        var requestedtemp = require(cwd + '/' + requestedtemp_input);
    } catch (e) {
        return console.error("Could not parse requestedtemp: ", e);
    }
    var reqtempstring;
    if (typeof requestedtemp.duration === 'undefined') {
        reqtempstring = "None";
    }
    else if (requestedtemp.duration < 1) {
        reqtempstring = "Cancel";
    } else {
        reqtempstring = requestedtemp.duration + "m@" + requestedtemp.rate.toFixed(1) + "U";
    }
    var enactedtemp = require(cwd + '/' + enactedtemp_input);
    if (enactedtemp.duration < 1) {
        enactedstring = "Cancel";
    } else {
        enactedstring = enactedtemp.duration + "m@" + enactedtemp.rate.toFixed(1) + "U";
    }
    tz = new Date().toString().match(/([-\+][0-9]+)\s/)[1]
    enactedDate = new Date(enactedtemp.timestamp.concat(tz));
    enactedHMS = enactedDate.toLocaleTimeString().split(":")
    enactedat = enactedHMS[0].concat(":", enactedHMS[1]);

    var mealCOB = "???";
    if (typeof meal_input != 'undefined') {
        try {
            meal_data = JSON.parse(fs.readFileSync(meal_input, 'utf8'));
            //console.error(JSON.stringify(meal_data));
            if (typeof meal_data.mealCOB != 'undefined') {
                mealCOB = meal_data.mealCOB;
            }
        } catch (e) {
            //console.error("Optional feature Meal Assist not configured.");
        }
    }

    var os = require("os");
    var host = os.hostname();

    var pebble = {
        "content" : "" + bgnow + requestedtemp.tick + " " + bgTime + "\n"
        + iob + "U->" + requestedtemp.eventualBG + "-" + requestedtemp.snoozeBG + "\n"
        //+ "Act: " + enactedstring
        //+ " at " + enactedat + "\n"
        + tempstring
        + " at " + temp_time + "\n"
        + "Req: " + reqtempstring + "\n"
        + requestedtemp.reason + "\n"
        + "Sched: " + basalRate + "U/hr\n"
        + "mealCOB: " + mealCOB + "g\n"
        + host + "\n",
        "refresh_frequency": 1
    };

    console.log(JSON.stringify(pebble));
}
<commit_msg>iob_data is now an array<commit_after>#!/usr/bin/env node

/*
  Update Pebble Watch information

  Copyright (c) 2015 OpenAPS Contributors

  Released under MIT license. See the accompanying LICENSE.txt file for
  full terms and conditions

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  THE SOFTWARE.

*/

function getTime(minutes) {
    var baseTime = new Date();
    baseTime.setHours('00');
    baseTime.setMinutes('00');
    baseTime.setSeconds('00');

    return baseTime.getTime() + minutes * 60 * 1000;

}

/* Return basal rate(U / hr) at the provided timeOfDay */

function basalLookup() {
    var now = new Date();
    basalRate = Math.round(basalprofile_data[basalprofile_data.length-1].rate*100)/100

    for (var i = 0; i < basalprofile_data.length - 1; i++) {
        if ((now >= getTime(basalprofile_data[i].minutes)) && (now < getTime(basalprofile_data[i + 1].minutes))) {
            basalRate = basalprofile_data[i].rate.toFixed(2);
            break;
        }
    }
}

function fileHM(file) {
    var filedate = new Date(fs.statSync(file).mtime);
    var HMS = filedate.toLocaleTimeString().split(":")
    return HMS[0].concat(":", HMS[1]);
}

if (!module.parent) {

    var fs = require('fs');

    var glucose_input = process.argv.slice(2, 3).pop()
    var iob_input = process.argv.slice(3, 4).pop()
    var basalprofile_input = process.argv.slice(4, 5).pop()
    var currenttemp_input = process.argv.slice(5, 6).pop()
    var requestedtemp_input = process.argv.slice(6, 7).pop()
    var enactedtemp_input = process.argv.slice(7, 8).pop()
    var meal_input = process.argv.slice(8, 9).pop()

    if (!glucose_input || !iob_input || !basalprofile_input || !currenttemp_input || !requestedtemp_input || !enactedtemp_input) {
        console.log('usage: ', process.argv.slice(0, 2), '<glucose.json> <iob.json> <current_basal_profile.json> <currenttemp.json> <requestedtemp.json> <enactedtemp.json> [meal.json]');
        process.exit(1);
    }

    var cwd = process.cwd()
    var file = cwd + '/' + glucose_input;
    var glucose_data = require(file);
    var bgTime = fileHM(file);
    if (glucose_data[0].dateString) {
        var bgDate = new Date(glucose_data[0].dateString);
        var HMS = bgDate.toLocaleTimeString().split(":")
        bgTime = HMS[0].concat(":", HMS[1]);
    }

    var bgnow = glucose_data[0].glucose;
    var iob_data = require(cwd + '/' + iob_input);
    iob = iob_data[0].iob.toFixed(1);
    var basalprofile_data = require(cwd + '/' + basalprofile_input);
    var basalRate;
    basalLookup();
    file = cwd + '/' + currenttemp_input;
    var temp = require(file);
    var temp_time = fileHM(file);
    var tempstring;
    if (temp.duration < 1) {
        tempstring = "No temp basal";
    } else {
        tempstring = "Tmp: " + temp.duration + "m@" + temp.rate.toFixed(1);
    }
    try {
        var requestedtemp = require(cwd + '/' + requestedtemp_input);
    } catch (e) {
        return console.error("Could not parse requestedtemp: ", e);
    }
    var reqtempstring;
    if (typeof requestedtemp.duration === 'undefined') {
        reqtempstring = "None";
    }
    else if (requestedtemp.duration < 1) {
        reqtempstring = "Cancel";
    } else {
        reqtempstring = requestedtemp.duration + "m@" + requestedtemp.rate.toFixed(1) + "U";
    }
    var enactedtemp = require(cwd + '/' + enactedtemp_input);
    if (enactedtemp.duration < 1) {
        enactedstring = "Cancel";
    } else {
        enactedstring = enactedtemp.duration + "m@" + enactedtemp.rate.toFixed(1) + "U";
    }
    tz = new Date().toString().match(/([-\+][0-9]+)\s/)[1]
    enactedDate = new Date(enactedtemp.timestamp.concat(tz));
    enactedHMS = enactedDate.toLocaleTimeString().split(":")
    enactedat = enactedHMS[0].concat(":", enactedHMS[1]);

    var mealCOB = "???";
    if (typeof meal_input != 'undefined') {
        try {
            meal_data = JSON.parse(fs.readFileSync(meal_input, 'utf8'));
            //console.error(JSON.stringify(meal_data));
            if (typeof meal_data.mealCOB != 'undefined') {
                mealCOB = meal_data.mealCOB;
            }
        } catch (e) {
            //console.error("Optional feature Meal Assist not configured.");
        }
    }

    var os = require("os");
    var host = os.hostname();

    var pebble = {
        "content" : "" + bgnow + requestedtemp.tick + " " + bgTime + "\n"
        + iob + "U->" + requestedtemp.eventualBG + "-" + requestedtemp.snoozeBG + "\n"
        //+ "Act: " + enactedstring
        //+ " at " + enactedat + "\n"
        + tempstring
        + " at " + temp_time + "\n"
        + "Req: " + reqtempstring + "\n"
        + requestedtemp.reason + "\n"
        + "Sched: " + basalRate + "U/hr\n"
        + "mealCOB: " + mealCOB + "g\n"
        + host + "\n",
        "refresh_frequency": 1
    };

    console.log(JSON.stringify(pebble));
}
<|endoftext|>


<commit_before>'use strict';

module.exports = function(app) {
    var config = require('../../config/config'),
        security = require('../../app/controllers/security'),
	    patients = require('../../app/controllers/patients'),
        multer =require('multer'),
        fileHandler =require('../../app/controllers/'+config.fileHandler+'-file-handle'),
        multerTemp=multer({ dest: config.filesTemp, limits: {
        fieldNameSize: 255,
            fields: 7,
            files: 1,
            fileSize:100000
    }});

	// Patients Routes
	/*app.route('/patients')
		.get(security.authorizedToDo('search_patients'), patients.search)
		.post(security.authorizedToDo('create_patient'), multerTemp, patients.create, fileHandler.uploadFile);*/

    app.route('/patients')
        .get(security.authorizedToDo('list_patients'), patients.list)
        .post(security.authorizedToDo('create_patient'), multerTemp, patients.create, fileHandler.uploadFile);

    app.route('/patients/search')
        .get(security.authorizedToDo('search_patients'), patients.search)

/*    app.route('/patients/search')
        .get(security.authorizedToDo('search_patients'), patients.search);*/

	app.route('/patients/:patientId')
		.get(security.authorizedToDo('view_patient'), patients.read)
		.put(security.authorizedToDo('edit_patient'), multerTemp, patients.update, fileHandler.uploadFile)
		.delete(security.authorizedToDo('delete_patient'), patients.delete);

    app.route('/patients/personal-photo/:patientId')
        .get(security.authorizedToDo(['list_patients', 'create_patient', 'edit_patient', 'view_patient']), patients.renderPhoto);

	// Finish by binding the Patient middleware
	app.param('patientId', patients.patientByID);
};
<commit_msg>- Patients Route<commit_after>'use strict';

module.exports = function(app) {
    var config = require('../../config/config'),
        security = require('../../app/controllers/security'),
	    patients = require('../../app/controllers/patients'),
        multer =require('multer'),
        fileHandler =require('../../app/controllers/'+config.fileHandler+'-file-handle'),
        multerTemp=multer({ dest: config.filesTemp, limits: {
        fieldNameSize: 255,
            fields: 7,
            files: 1,
            fileSize:100000
    }});

	// Patients Routes
	/*app.route('/patients')
		.get(security.authorizedToDo('list_patients'), patients.search)
		.post(security.authorizedToDo('create_patient'), multerTemp, patients.create, fileHandler.uploadFile);*/

    app.route('/patients')
        .get(security.authorizedToDo('list_patients'), patients.list)
        .post(security.authorizedToDo('create_patient'), multerTemp, patients.create, fileHandler.uploadFile);

    app.route('/patients/search')
        .get(security.authorizedToDo('list_patients'), patients.search)

/*    app.route('/patients/search')
        .get(security.authorizedToDo('list_patients'), patients.search);*/

	app.route('/patients/:patientId')
		.get(security.authorizedToDo('view_patient'), patients.read)
		.put(security.authorizedToDo('edit_patient'), multerTemp, patients.update, fileHandler.uploadFile)
		.delete(security.authorizedToDo('delete_patient'), patients.delete);

    app.route('/patients/personal-photo/:patientId')
        .get(security.authorizedToDo(['list_patients', 'create_patient', 'edit_patient', 'view_patient']), patients.renderPhoto);

	// Finish by binding the Patient middleware
	app.param('patientId', patients.patientByID);
};
<|endoftext|>


<commit_before>const chai = require('chai');
const assert = chai.assert;
const BodyPart = require('../lib/snake');

describe('my test suite', function () {
  it('should work', function () {
      assert(true);
  });
});

describe('Snake', function () {
  it('exists', function () {
    assert(new BodyPart);
  });

  // it('should instantiate with an x, y, height, and width', function(){
  //     let bodyPart = new BodyPart(20, 20, 30, 30);
  //     assert.equal(bodyPart.x, 20);
  //     assert.equal(bodyPart.width, 30);
  //     assert.equal(bodyPart.height, 30);
  //     assert.equal(bodyPart.y, 20);
  // });
});
<commit_msg>it instantiates with x, y, height, width<commit_after>const chai = require('chai');
const assert = chai.assert;
const BodyPart = require('../lib/snake');

describe('Snake', function () {
  it('exists', function () {
    assert(new BodyPart);
  });

  it('should instantiate with an x, y, height, and width', function(){
      let bodyPart = new BodyPart(20, 20, 30, 30);
      assert.equal(bodyPart.x, 20);
      assert.equal(bodyPart.y, 20);
      assert.equal(bodyPart.width, 30);
      assert.equal(bodyPart.height, 30);
  });
});
<|endoftext|>


<commit_before>define(["mobileui/ui/navigator-card-view",
        "mobileui/utils/transform",
        "mobileui/utils/filter",
        "mobileui/utils/momentum",
        "mobileui/views/gesture-detector",
        "app"],
    function(NavigatorCardView, Transform, Filter, Momentum, GestureDetector, app) {

    var AppCardView = NavigatorCardView.extend({
        initialize: function() {
            AppCardView.__super__.initialize.call(this);
            this.addGestureDetector();
            this.on("touchdragstart", this._onDragStart, this)
                .on("touchdragmove", this._onDragMove, this)
                .on("touchdragend", this._onDragEnd, this);
            this._momentum = new Momentum().setDuration(300).setFriction(0.000005);
            this._dragStartValue = 0;
            this.on("card:precommit", this._updateBackButton, this);
            this.on("activate", this._updateBackButton, this);
            this.forceLayer();
        },

        _updateBackButton: function() {
            app.mainView.navigatorView().updateBackButton();
        },

        render: function() {
            this.$el.addClass("js-app-card-view");
            return AppCardView.__super__.render.call(this);
        },

        respondsToTouchGesture: function(gesture) {
            if (gesture.type != GestureDetector.GestureType.DRAG)
                return false;
            return (gesture.scrollX && gesture.distanceX < 0 &&
                app.mainView.navigatorView().activeCard() === this &&
                app.mainView.navigatorView().canGoBack());
        },

        _onDragStart: function() {
            var nextCard = app.mainView.navigatorView().prepareHistoryCard().nextCard();
            nextCard.filter().get("grayscale").setIntensity(100);
            var translate = this.transform().get("translate");
            this._dragStartValue = translate.x();
            this._momentum.reset(this._dragStartValue);
        },

        _onDragMove: function(transform) {
            var translate = this.transform().get("translate"),
                value = Math.max(0, this._dragStartValue + transform.dragX);
            translate.setX(value);
            var nextCard = app.mainView.navigatorView().nextCard();
            nextCard.filter().get("grayscale").setIntensity(100 - value / this.bounds().width() * 100);
            this._momentum.injectValue(value);
        },

        _onDragEnd: function(transform) {
            this._onDragMove(transform);
            var value = this._momentum.compute() * 4,
                direction = this._momentum.direction();
            if ((value < this.bounds().width()) || (direction > 0))
                return this._revert();
            this._commit();
        },

        _commit: function() {
            var self = this,
                nextCard = app.mainView.navigatorView().nextCard();
            app.mainView.navigatorView().precommitNextCard();
            var transform = new Transform().translate(this.bounds().width(), 0);
            this.animation().start().get("slide-transform")
                .chain()
                .transform(300, transform)
                .wait(100)
                .callback(function() {
                    nextCard.filter().clear();
                    app.mainView.navigatorView().commitNextCard();
                });
            this.animation().get("slide")
                .chain()
                .opacity(300, 100);
            nextCard.animation().start().get("slide-filter")
                .chain()
                .filter(300, new Filter().grayscale(0));
        },

        _revert: function() {
            var self = this,
                nextCard = app.mainView.navigatorView().nextCard(),
                transform = new Transform();
            this.animation().start().get("slide-transform").chain()
                .transform(100, transform)
                .callback(function() {
                    nextCard.filter().clear();
                    app.mainView.navigatorView().revertNextCard();
                });
            this.animation().get("slide")
                .chain()
                .opacity(100, 1);
            nextCard.animation().start().get("slide-filter")
                .chain()
                .filter(300, new Filter().grayscale(100));
        },

        url: function() {
            return null;
        },

        updateRouterLocation: function() {
            var url = this.url();
            if (!url)
                return;
            app.router.navigate(url, { trigger: false });
        }
    });

    return AppCardView;

});<commit_msg>remove the filter after canceling the slide left swipe<commit_after>define(["mobileui/ui/navigator-card-view",
        "mobileui/utils/transform",
        "mobileui/utils/filter",
        "mobileui/utils/momentum",
        "mobileui/views/gesture-detector",
        "app"],
    function(NavigatorCardView, Transform, Filter, Momentum, GestureDetector, app) {

    var AppCardView = NavigatorCardView.extend({
        initialize: function() {
            AppCardView.__super__.initialize.call(this);
            this.addGestureDetector();
            this.on("touchdragstart", this._onDragStart, this)
                .on("touchdragmove", this._onDragMove, this)
                .on("touchdragend", this._onDragEnd, this);
            this._momentum = new Momentum().setDuration(300).setFriction(0.000005);
            this._dragStartValue = 0;
            this.on("card:precommit", this._updateBackButton, this);
            this.on("activate", this._updateBackButton, this);
            this.forceLayer();
        },

        _updateBackButton: function() {
            app.mainView.navigatorView().updateBackButton();
        },

        render: function() {
            this.$el.addClass("js-app-card-view");
            return AppCardView.__super__.render.call(this);
        },

        respondsToTouchGesture: function(gesture) {
            if (gesture.type != GestureDetector.GestureType.DRAG)
                return false;
            return (gesture.scrollX && gesture.distanceX < 0 &&
                app.mainView.navigatorView().activeCard() === this &&
                app.mainView.navigatorView().canGoBack());
        },

        _onDragStart: function() {
            var nextCard = app.mainView.navigatorView().prepareHistoryCard().nextCard();
            nextCard.filter().get("grayscale").setIntensity(100);
            var translate = this.transform().get("translate");
            this._dragStartValue = translate.x();
            this._momentum.reset(this._dragStartValue);
        },

        _onDragMove: function(transform) {
            var translate = this.transform().get("translate"),
                value = Math.max(0, this._dragStartValue + transform.dragX);
            translate.setX(value);
            var nextCard = app.mainView.navigatorView().nextCard();
            nextCard.filter().get("grayscale").setIntensity(100 - value / this.bounds().width() * 100);
            this._momentum.injectValue(value);
        },

        _onDragEnd: function(transform) {
            this._onDragMove(transform);
            var value = this._momentum.compute() * 4,
                direction = this._momentum.direction();
            if ((value < this.bounds().width()) || (direction > 0))
                return this._revert();
            this._commit();
        },

        _commit: function() {
            var self = this,
                nextCard = app.mainView.navigatorView().nextCard();
            app.mainView.navigatorView().precommitNextCard();
            var transform = new Transform().translate(this.bounds().width(), 0);
            this.animation().start().get("slide-transform")
                .chain()
                .transform(300, transform)
                .wait(100)
                .callback(function() {
                    nextCard.filter().clear();
                    app.mainView.navigatorView().commitNextCard();
                });
            this.animation().get("slide")
                .chain()
                .opacity(300, 100);
            nextCard.animation().start().get("slide-filter")
                .chain()
                .filter(300, new Filter().grayscale(0));
        },

        _revert: function() {
            var self = this,
                nextCard = app.mainView.navigatorView().nextCard(),
                transform = new Transform();
            this.animation().start().get("slide-transform").chain()
                .transform(100, transform)
                .callback(function() {
                    app.mainView.navigatorView().revertNextCard();
                });
            this.animation().get("slide")
                .chain()
                .opacity(100, 1);
            nextCard.animation().start().get("slide-filter")
                .chain()
                .filter(100, new Filter().grayscale(100))
                .callback(function() {
                    nextCard.filter().clear();
                });
        },

        url: function() {
            return null;
        },

        updateRouterLocation: function() {
            var url = this.url();
            if (!url)
                return;
            app.router.navigate(url, { trigger: false });
        }
    });

    return AppCardView;

});<|endoftext|>


<commit_before>const chai = require('chai');
const chaiImmutable = require('chai-immutable');

chai.use(chaiImmutable);

import { dummyStore } from '../../utils';

import { ActionsObservable } from 'redux-observable';

const Immutable = require('immutable');

const fromJS = Immutable.fromJS;

const expect = chai.expect;

const sinon = require('sinon');

const Rx = require('rxjs/Rx');

const Observable = Rx.Observable;
import { EXECUTE_CELL } from '../../../src/notebook/constants';
import { executeCell } from '../../../src/notebook/actions';
import {
  reduceOutputs,
  executeCellObservable,
  executeCellEpic,
  createExecuteRequest,
  msgSpecToNotebookFormat,
  createPagerActions,
  createSourceUpdateAction,
  createCellAfterAction,
  createCellStatusAction,
  createExecuteCellObservable,
  updateCellNumberingAction,
  handleFormattableMessages,
} from '../../../src/notebook/epics/execute';

describe('executeCell', () => {
  it('returns an executeCell action', () => {
    expect(executeCell('0-0-0-0', 'import random; random.random()'))
      .to.deep.equal({
        type: EXECUTE_CELL,
        id: '0-0-0-0',
        source: 'import random; random.random()',
      });
  });
});

describe('reduceOutputs', () => {
  it('empties outputs when clear_output passed', () => {
    const outputs = Immutable.List([1,2,3]);
    const newOutputs = reduceOutputs(outputs, {output_type: 'clear_output'});
    expect(newOutputs.size).to.equal(0);
  })

  it('puts new outputs at the end by default', () => {
    const outputs = Immutable.List([1,2]);
    const newOutputs = reduceOutputs(outputs, 3)

    expect(newOutputs).to.equal(Immutable.List([1, 2, 3]));
  })

  it('merges streams of text', () => {
    const outputs = Immutable.fromJS([{name: 'stdout', text: 'hello', output_type: 'stream'}])
    const newOutputs = reduceOutputs(outputs, {name: 'stdout', text: ' world', output_type: 'stream' });

    expect(newOutputs).to.equal(Immutable.fromJS([{name: 'stdout', text: 'hello world', output_type: 'stream'}]));
  })

  it('keeps respective streams together', () => {
    const outputs = Immutable.fromJS([
      {name: 'stdout', text: 'hello', output_type: 'stream'},
      {name: 'stderr', text: 'errors are', output_type: 'stream'},
    ])
    const newOutputs = reduceOutputs(outputs, {name: 'stdout', text: ' world', output_type: 'stream' });

    expect(newOutputs).to.equal(Immutable.fromJS([
      {name: 'stdout', text: 'hello world', output_type: 'stream'},
      {name: 'stderr', text: 'errors are', output_type: 'stream'},
    ]));

    const evenNewerOutputs = reduceOutputs(newOutputs, {name: 'stderr', text: ' informative', output_type: 'stream' });
    expect(evenNewerOutputs).to.equal(Immutable.fromJS([
      {name: 'stdout', text: 'hello world', output_type: 'stream'},
      {name: 'stderr', text: 'errors are informative', output_type: 'stream'},
    ]));

  })
})

describe('executeCellObservable', () => {
  // TODO: Refactor executeCellObservable into separate testable observables
  it('is entirely too insane for me to test this well right this second', (done) => {
    const frontendToShell = new Rx.Subject();
    const shellToFrontend = new Rx.Subject();
    const mockShell = Rx.Subject.create(frontendToShell, shellToFrontend);
    const mockIOPub = new Rx.Subject();

    const channels = {
      shell: mockShell,
      iopub: mockIOPub,
    };

    // Expect message to have been sent
    frontendToShell
      .subscribe(msg => {
        expect(msg.header.msg_type).to.equal('execute_request');
        expect(msg.content.code).to.equal('import this');
      })

    const action$ = executeCellObservable(channels, '0', 'import this');

    action$
      .bufferCount(3)
      .subscribe(messages => {
        expect(messages).to.deep.equal([
          // TODO: Order doesn't actually matter here
          { type: 'UPDATE_CELL_STATUS', id: '0', status: 'busy' },
          { type: 'UPDATE_CELL_PAGERS', id: '0', pagers: Immutable.List() },
          { type: 'UPDATE_CELL_OUTPUTS', id: '0', outputs: Immutable.List() },
        ]);
        done(); // TODO: Make sure message check above is called
      })

  })

  it('outright rejects a lack of channels.shell and iopub', (done) => {
    const obs = executeCellObservable({}, '0', 'woo')
    obs.subscribe(null, (err) => {
        expect(err.message).to.equal('kernel not connected');
        done();
    })

  })
});

describe('createExecuteRequest', () => {
  it('creates an execute_request message', () => {
    const code = 'print("test")';
    const executeRequest = createExecuteRequest(code);

    expect(executeRequest.content.code).to.equal(code);
    expect(executeRequest.header.msg_type).to.equal('execute_request');
  });
});

describe('msgSpecToNotebookFormat', () => {
  it('converts a message to the notebook format', () => {
    const msg = {content: {data: 'test'}, header: {msg_type: 'test_header'}};
    const notebookSpecMsg = msgSpecToNotebookFormat(msg);

    expect(notebookSpecMsg).to.have.property('output_type');
    expect(notebookSpecMsg).to.have.property('data');
    expect(notebookSpecMsg.output_type).to.equal('test_header');
  });
});

describe('createPagerActions', () => {
  it('emits actions to set pagers', (done) => {
    const msgObs = Rx.Observable.from([{
      source: 'page',
      data: {'text/html': 'this is a test'},
    }]);

    const pagerAction$ = createPagerActions('1', msgObs);

    pagerAction$.subscribe((action) => {
      const expected = [{ source: 'page', data: { 'text/html': 'this is a test' } } ];
      expect(action.id).to.equal('1');
      expect(action.pagers.toJS()).to.deep.equal(expected);
      done();
    });
  });
});

describe('createCellAfterAction', () => {
  it('emits a createCellAfter action', (done) => {
    const msgObs = Rx.Observable.from([{
      source: 'set_next_input',
      text: 'This is some test text.',
      replace: false,
    }]);

    const cellAction$ = createCellAfterAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.id).to.equal('1');
      done();
    });
  });
});

describe('createCellStatusAction', () => {
  it('emits an updateCellStatus action', (done) => {
    const msgObs = Rx.Observable.from([{
      header: {
        msg_id: '123',
        msg_type: 'status',
      },
      parent_header: {},
      content: {
        'execution_state': 'idle',
      },
      metadata: {},
    }]);

    const cellAction$ = createCellStatusAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.id).to.equal('1');
      expect(action.status).to.equal('idle');
      done();
    });
  });
});

describe('updateCellNumberingAction', () => {
  it('emits updateCellExecutionCount action', (done) => {
    const msgObs = Rx.Observable.from([{
      header: {
        msg_id: '123',
        msg_type: 'execute_input',
      },
      parent_header: {},
      content: {
        'execution_count': 3,
      },
      metadata: {},
    }]);

    const cellAction$ = updateCellNumberingAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.id).to.equal('1');
      expect(action.count).to.equal(3);
      done();
    });
  });
});

describe('createSourceUpdateAction', () => {
  it('emits updateCellSource action', (done) => {
    const msgObs = Rx.Observable.from([{
      source: 'set_next_input',
      text: 'This is some test text.',
      replace: true,
    }]);

    const cellAction$ = createSourceUpdateAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.source).to.equal('This is some test text.');
      done();
    });
  });
});
describe('createExecuteCellObservable', () => {
  let store = { getState: function() { return this.state; },
            state: {
              app: {
                executionState: 'starting',
                channels: 'channelInfo',
                notificationSystem: {
                  addNotification: sinon.spy(),
                },
              }
            },
          };
  const action$ = new ActionsObservable();
  it('notifies the user if kernel is not connected', () => {
    const testFunction = createExecuteCellObservable(action$, store, 'source', 'id');
    const notification = store.getState().app.notificationSystem.addNotification;
    expect(notification).to.be.calledWith({
      title: 'Could not execute cell',
      message: 'The cell could not be executed because the kernel is not connected.',
      level: 'error',
    });
    expect(testFunction.subscribe).to.not.be.null;
  });
  it('emits returns an observable when kernel connected', () => {
    store.state.app.executionState = 'started'
    const executeCellObservable = createExecuteCellObservable(action$, store, 'source', 'id');
    expect(executeCellObservable.subscribe).to.not.be.null;
  });
})

describe('executeCellEpic', () => {
  const store = { getState: function() { return this.state; },
            state: {
              app: {
                executionState: 'starting',
                channels: 'channelInfo',
                notificationSystem: {
                  addNotification: sinon.spy(),
                },
                token: 'blah'
              }
            },
          };
  it('Errors on a bad action', () => {
    const badInput$ = Observable.of({ type: EXECUTE_CELL });
    const badAction$ = new ActionsObservable(badInput$);
    const actionBuffer = [];
    const responseActions = executeCellEpic(badAction$, store);
    const subscription = responseActions.subscribe(
      actionBuffer.push, // Every action that goes through should get stuck on an array
      (err) => expect.fail(err, null), // It should not error in the stream
      () => {
        expect(actionBuffer).to.deep.equal([]); // ;
      },
    );
  });
  it('Runs an epic with the approriate flow with good action', () => {
    const input$ = Observable.of(executeCell('id', 'source'));
    const action$ = new ActionsObservable(input$);
    const actionBuffer = [];
    const responseActions = executeCellEpic(action$, store);
    const subscription = responseActions.subscribe(
      actionBuffer.push, // Every action that goes through should get stuck on an array
      (err) => expect.fail(err, null), // It should not error in the stream
      () => {
        expect(actionBuffer).to.deep.equal([]); // ;
      },
    );
  });
})
<commit_msg>chore(ExecuteEpic): Try to have test expect error.<commit_after>const chai = require('chai');
const chaiImmutable = require('chai-immutable');

chai.use(chaiImmutable);

import { dummyStore } from '../../utils';

import { ActionsObservable } from 'redux-observable';

const Immutable = require('immutable');

const fromJS = Immutable.fromJS;

const expect = chai.expect;

const sinon = require('sinon');

const Rx = require('rxjs/Rx');

const Observable = Rx.Observable;
import { EXECUTE_CELL } from '../../../src/notebook/constants';
import { executeCell } from '../../../src/notebook/actions';
import {
  reduceOutputs,
  executeCellObservable,
  executeCellEpic,
  createExecuteRequest,
  msgSpecToNotebookFormat,
  createPagerActions,
  createSourceUpdateAction,
  createCellAfterAction,
  createCellStatusAction,
  createExecuteCellObservable,
  updateCellNumberingAction,
  handleFormattableMessages,
} from '../../../src/notebook/epics/execute';

describe('executeCell', () => {
  it('returns an executeCell action', () => {
    expect(executeCell('0-0-0-0', 'import random; random.random()'))
      .to.deep.equal({
        type: EXECUTE_CELL,
        id: '0-0-0-0',
        source: 'import random; random.random()',
      });
  });
});

describe('reduceOutputs', () => {
  it('empties outputs when clear_output passed', () => {
    const outputs = Immutable.List([1,2,3]);
    const newOutputs = reduceOutputs(outputs, {output_type: 'clear_output'});
    expect(newOutputs.size).to.equal(0);
  })

  it('puts new outputs at the end by default', () => {
    const outputs = Immutable.List([1,2]);
    const newOutputs = reduceOutputs(outputs, 3)

    expect(newOutputs).to.equal(Immutable.List([1, 2, 3]));
  })

  it('merges streams of text', () => {
    const outputs = Immutable.fromJS([{name: 'stdout', text: 'hello', output_type: 'stream'}])
    const newOutputs = reduceOutputs(outputs, {name: 'stdout', text: ' world', output_type: 'stream' });

    expect(newOutputs).to.equal(Immutable.fromJS([{name: 'stdout', text: 'hello world', output_type: 'stream'}]));
  })

  it('keeps respective streams together', () => {
    const outputs = Immutable.fromJS([
      {name: 'stdout', text: 'hello', output_type: 'stream'},
      {name: 'stderr', text: 'errors are', output_type: 'stream'},
    ])
    const newOutputs = reduceOutputs(outputs, {name: 'stdout', text: ' world', output_type: 'stream' });

    expect(newOutputs).to.equal(Immutable.fromJS([
      {name: 'stdout', text: 'hello world', output_type: 'stream'},
      {name: 'stderr', text: 'errors are', output_type: 'stream'},
    ]));

    const evenNewerOutputs = reduceOutputs(newOutputs, {name: 'stderr', text: ' informative', output_type: 'stream' });
    expect(evenNewerOutputs).to.equal(Immutable.fromJS([
      {name: 'stdout', text: 'hello world', output_type: 'stream'},
      {name: 'stderr', text: 'errors are informative', output_type: 'stream'},
    ]));

  })
})

describe('executeCellObservable', () => {
  // TODO: Refactor executeCellObservable into separate testable observables
  it('is entirely too insane for me to test this well right this second', (done) => {
    const frontendToShell = new Rx.Subject();
    const shellToFrontend = new Rx.Subject();
    const mockShell = Rx.Subject.create(frontendToShell, shellToFrontend);
    const mockIOPub = new Rx.Subject();

    const channels = {
      shell: mockShell,
      iopub: mockIOPub,
    };

    // Expect message to have been sent
    frontendToShell
      .subscribe(msg => {
        expect(msg.header.msg_type).to.equal('execute_request');
        expect(msg.content.code).to.equal('import this');
      })

    const action$ = executeCellObservable(channels, '0', 'import this');

    action$
      .bufferCount(3)
      .subscribe(messages => {
        expect(messages).to.deep.equal([
          // TODO: Order doesn't actually matter here
          { type: 'UPDATE_CELL_STATUS', id: '0', status: 'busy' },
          { type: 'UPDATE_CELL_PAGERS', id: '0', pagers: Immutable.List() },
          { type: 'UPDATE_CELL_OUTPUTS', id: '0', outputs: Immutable.List() },
        ]);
        done(); // TODO: Make sure message check above is called
      })

  })

  it('outright rejects a lack of channels.shell and iopub', (done) => {
    const obs = executeCellObservable({}, '0', 'woo')
    obs.subscribe(null, (err) => {
        expect(err.message).to.equal('kernel not connected');
        done();
    })

  })
});

describe('createExecuteRequest', () => {
  it('creates an execute_request message', () => {
    const code = 'print("test")';
    const executeRequest = createExecuteRequest(code);

    expect(executeRequest.content.code).to.equal(code);
    expect(executeRequest.header.msg_type).to.equal('execute_request');
  });
});

describe('msgSpecToNotebookFormat', () => {
  it('converts a message to the notebook format', () => {
    const msg = {content: {data: 'test'}, header: {msg_type: 'test_header'}};
    const notebookSpecMsg = msgSpecToNotebookFormat(msg);

    expect(notebookSpecMsg).to.have.property('output_type');
    expect(notebookSpecMsg).to.have.property('data');
    expect(notebookSpecMsg.output_type).to.equal('test_header');
  });
});

describe('createPagerActions', () => {
  it('emits actions to set pagers', (done) => {
    const msgObs = Rx.Observable.from([{
      source: 'page',
      data: {'text/html': 'this is a test'},
    }]);

    const pagerAction$ = createPagerActions('1', msgObs);

    pagerAction$.subscribe((action) => {
      const expected = [{ source: 'page', data: { 'text/html': 'this is a test' } } ];
      expect(action.id).to.equal('1');
      expect(action.pagers.toJS()).to.deep.equal(expected);
      done();
    });
  });
});

describe('createCellAfterAction', () => {
  it('emits a createCellAfter action', (done) => {
    const msgObs = Rx.Observable.from([{
      source: 'set_next_input',
      text: 'This is some test text.',
      replace: false,
    }]);

    const cellAction$ = createCellAfterAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.id).to.equal('1');
      done();
    });
  });
});

describe('createCellStatusAction', () => {
  it('emits an updateCellStatus action', (done) => {
    const msgObs = Rx.Observable.from([{
      header: {
        msg_id: '123',
        msg_type: 'status',
      },
      parent_header: {},
      content: {
        'execution_state': 'idle',
      },
      metadata: {},
    }]);

    const cellAction$ = createCellStatusAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.id).to.equal('1');
      expect(action.status).to.equal('idle');
      done();
    });
  });
});

describe('updateCellNumberingAction', () => {
  it('emits updateCellExecutionCount action', (done) => {
    const msgObs = Rx.Observable.from([{
      header: {
        msg_id: '123',
        msg_type: 'execute_input',
      },
      parent_header: {},
      content: {
        'execution_count': 3,
      },
      metadata: {},
    }]);

    const cellAction$ = updateCellNumberingAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.id).to.equal('1');
      expect(action.count).to.equal(3);
      done();
    });
  });
});

describe('createSourceUpdateAction', () => {
  it('emits updateCellSource action', (done) => {
    const msgObs = Rx.Observable.from([{
      source: 'set_next_input',
      text: 'This is some test text.',
      replace: true,
    }]);

    const cellAction$ = createSourceUpdateAction('1', msgObs);

    cellAction$.subscribe((action) => {
      expect(action.source).to.equal('This is some test text.');
      done();
    });
  });
});
describe('createExecuteCellObservable', () => {
  let store = { getState: function() { return this.state; },
            state: {
              app: {
                executionState: 'starting',
                channels: 'channelInfo',
                notificationSystem: {
                  addNotification: sinon.spy(),
                },
              }
            },
          };
  const action$ = new ActionsObservable();
  it('notifies the user if kernel is not connected', () => {
    const testFunction = createExecuteCellObservable(action$, store, 'source', 'id');
    const notification = store.getState().app.notificationSystem.addNotification;
    expect(notification).to.be.calledWith({
      title: 'Could not execute cell',
      message: 'The cell could not be executed because the kernel is not connected.',
      level: 'error',
    });
    expect(testFunction.subscribe).to.not.be.null;
  });
  it('emits returns an observable when kernel connected', () => {
    store.state.app.executionState = 'started'
    const executeCellObservable = createExecuteCellObservable(action$, store, 'source', 'id');
    expect(executeCellObservable.subscribe).to.not.be.null;
  });
})

describe('executeCellEpic', () => {
  const store = { getState: function() { return this.state; },
            state: {
              app: {
                executionState: 'starting',
                channels: 'channelInfo',
                notificationSystem: {
                  addNotification: sinon.spy(),
                },
                token: 'blah'
              }
            },
          };
  it('Errors on a bad action', () => {
    const badInput$ = Observable.of({ type: EXECUTE_CELL });
    const badAction$ = new ActionsObservable(badInput$);
    const actionBuffer = [];
    const responseActions = executeCellEpic(badAction$, store).catch(error => {
      expect(error.message).to.equal('execute cell needs an id');
      done();
    });
    const subscription = responseActions.subscribe(
      actionBuffer.push, // Every action that goes through should get stuck on an array
      (err) => expect.fail(err, null), // It should not error in the stream
      () => {
        expect(actionBuffer).to.deep.equal([]); // ;
      },
    );
  });
  it('Errors on an action where source not a string', () => {
    const badInput$ = Observable.of(executeCell('id', 2));
    const badAction$ = new ActionsObservable(badInput$);
    const actionBuffer = [];
    const responseActions = executeCellEpic(badAction$, store).catch(error=> {
      expect(error.message).to.equal('execute cell needs source string');
      done();
    });
    const subscription = responseActions.subscribe(
      actionBuffer.push, // Every action that goes through should get stuck on an array
      (err) => expect.fail(err, null), // It should not error in the stream
      () => {
        expect(actionBuffer).to.deep.equal([]); // ;
      }
    );
  });
  it('Runs an epic with the approriate flow with good action', () => {
    const input$ = Observable.of(executeCell('id', 'source'));
    const action$ = new ActionsObservable(input$);
    const actionBuffer = [];
    const responseActions = executeCellEpic(action$, store);
    const subscription = responseActions.subscribe(
      actionBuffer.push, // Every action that goes through should get stuck on an array
      (err) => expect.fail(err, null), // It should not error in the stream
      () => {
        expect(actionBuffer).to.deep.equal([]); // ;
      },
    );
  });
})
<|endoftext|>


<commit_before>var gingApp = gingApp || angular.module('gingApp');

gingApp.directive('resultsPagination', function(){
    return {
      templateUrl: 'views/_pagination.html'
    };
});
<commit_msg>updated the partial path<commit_after>var gingApp = gingApp || angular.module('gingApp');

gingApp.directive('resultsPagination', function(){
    return {
      templateUrl: 'views/pagination.html'
    };
});
<|endoftext|>


<commit_before>define(["./_base", "dojo/has!gfx-no-compat?:./compat"], function (gfx) {
	// module:
	//		gfx
	// summary:
	//		This the root of the Dojo Graphics package.
	//		Loads the gfx/compat module (this may be changed before 2.0 is released).
	return gfx;
});
<commit_msg>Removed dojo/has! plugin call in main gfx.js, the flag that it tests is not used and this seems to break tests on Travis?...<commit_after>define(["./_base", "./compat"], function (gfx) {
	// module:
	//		gfx
	// summary:
	//		This the root of the Dojo Graphics package.
	//		Loads the gfx/compat module (this may be changed before 2.0 is released).
	return gfx;
});
<|endoftext|>