<commit_before>'use strict';

/* jasmine specs for services go here */

describe('service', function() {
  beforeEach(module('bottleRocket.services'));

  // Spec Template from Angular-Seed
  // describe('version', function() {
  //   it('should return current version', inject(function(version) {
  //     expect(version).toEqual('0.1');
  //   }));
  // });

  // Testing API calls using ngMock instead of Sinon because ngMock is built into Angular
  // https://docs.angularjs.org/api/ngMock/service/$httpBackend

  // Used this to help set up $httpBackend:
  // http://stackoverflow.com/questions/15927919/using-ngmock-to-simulate-http-calls-in-service-unit-tests

  var $httpBackend;

  beforeEach(inject(function ($injector) {
    $httpBackend = $injector.get("$httpBackend");

    // configure the requests

    // Seevl Requests
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/?prefLabel=nirvana&user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotSearchDataFromSeevl"});
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/RkMQZrfG/infos?user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotInfoDataFromSeevl"});
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/RkMQZrfG/related?user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotRelatedDataFromSeevl"});
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/RkMQZrfG/facts?user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotFactsDataFromSeevl"});

    // YouTube Request
    $httpBackend
        .when("JSONP", "http://gdata.youtube.com/feeds/api/videos?q=nirvana&format=5&max-results=1&v=2&alt=jsonc&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotVideoFromYoutube"});

    // Rotten Tomatoes
    $httpBackend
        .when("JSONP", "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json?page_limit=16&page=1&country=ie&apikey=2fu8bhwngnxuc6a56pburxfm&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotMoviesFromRottenTomatoes"});

  }));

  afterEach(function () {
    $httpBackend.flush()
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  describe('seevlService tests', function() {

  	describe('seevlService Search http request', function () {
  		it('.value should be "gotSearchDataFromSeevl', inject(function (seevlService) {

  			seevlService.search("nirvana").success(function(response) {
  		  		expect(response.value).toEqual("gotSearchDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  	describe('seevlService Info http request', function () {
  		it('.value should be "gotInfoDataFromSeevl', inject(function (seevlService) {

  			seevlService.getInfo("RkMQZrfG").success(function(response) {
  		  		expect(response.value).toEqual("gotInfoDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  	describe('seevlService Related http request', function () {
  		it('.value should be "gotRelatedDataFromSeevl', inject(function (seevlService) {

  			seevlService.getRelated("RkMQZrfG").success(function(response) {
  		  		expect(response.value).toEqual("gotRelatedDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  	describe('seevlService Facts http request', function () {
  		it('.value should be "gotFactsDataFromSeevl', inject(function (seevlService) {

  			seevlService.getFacts("RkMQZrfG").success(function(response) {
  		  		expect(response.value).toEqual("gotFactsDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  });

  describe('youtubeService test', function() {
  	it('.value should be "gotVideoFromYoutube', inject(function (youtubeService) {

  		youtubeService.search("nirvana").success(function(response) {
  			expect(response.value).toEqual("gotVideoFromYoutube");
  		}).error( function(response) {
  			expect(false).toEqual(true);
  		});

  	}));
  });

  describe('youtubeFactory test', function() {
  	it('.value should be "gotMoviesFromRottenTomatoes', inject(function (rottentomatoesFactory) {

  		rottentomatoesFactory.getMovies().success(function(response) {
  			expect(response.value).toEqual("gotMoviesFromRottenTomatoes");
  		}).error( function(response) {
  			expect(false).toEqual(true);
  		});

  	}));
  });

});
<commit_msg>Added test for bandsintownService<commit_after>'use strict';

/* jasmine specs for services go here */

describe('service', function() {
  beforeEach(module('bottleRocket.services'));

  // Spec Template from Angular-Seed
  // describe('version', function() {
  //   it('should return current version', inject(function(version) {
  //     expect(version).toEqual('0.1');
  //   }));
  // });

  // Testing API calls using ngMock instead of Sinon because ngMock is built into Angular
  // https://docs.angularjs.org/api/ngMock/service/$httpBackend

  // Used this to help set up $httpBackend:
  // http://stackoverflow.com/questions/15927919/using-ngmock-to-simulate-http-calls-in-service-unit-tests

  var $httpBackend;

  beforeEach(inject(function ($injector) {
    $httpBackend = $injector.get("$httpBackend");

    // configure the requests

    // Seevl Requests
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/?prefLabel=nirvana&user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotSearchDataFromSeevl"});
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/RkMQZrfG/infos?user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotInfoDataFromSeevl"});
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/RkMQZrfG/related?user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotRelatedDataFromSeevl"});
    $httpBackend
        .when("JSONP", "http://data.seevl.fm/entities/RkMQZrfG/facts?user_key=f934179d7329edcc16058765fb653a77&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotFactsDataFromSeevl"});

    // YouTube Request
    $httpBackend
        .when("JSONP", "http://gdata.youtube.com/feeds/api/videos?q=nirvana&format=5&max-results=1&v=2&alt=jsonc&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotVideoFromYoutube"});

    // Rotten Tomatoes request
    $httpBackend
        .when("JSONP", "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json?page_limit=16&page=1&country=ie&apikey=2fu8bhwngnxuc6a56pburxfm&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotMoviesFromRottenTomatoes"});

    // BandsInTown request
    $httpBackend
        .when("JSONP", "http://api.bandsintown.com/artists/Skrillex.json?api_version=2.0&app_id=bottleRocket&callback=JSON_CALLBACK")
        	.respond(200, {value: "gotBandFromBandsInTown"});

  }));

  afterEach(function () {
    $httpBackend.flush()
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  describe('seevlService tests', function() {

  	describe('seevlService Search http request', function () {
  		it('.value should be "gotSearchDataFromSeevl', inject(function (seevlService) {

  			seevlService.search("nirvana").success(function(response) {
  		  		expect(response.value).toEqual("gotSearchDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  	describe('seevlService Info http request', function () {
  		it('.value should be "gotInfoDataFromSeevl', inject(function (seevlService) {

  			seevlService.getInfo("RkMQZrfG").success(function(response) {
  		  		expect(response.value).toEqual("gotInfoDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  	describe('seevlService Related http request', function () {
  		it('.value should be "gotRelatedDataFromSeevl', inject(function (seevlService) {

  			seevlService.getRelated("RkMQZrfG").success(function(response) {
  		  		expect(response.value).toEqual("gotRelatedDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  	describe('seevlService Facts http request', function () {
  		it('.value should be "gotFactsDataFromSeevl', inject(function (seevlService) {

  			seevlService.getFacts("RkMQZrfG").success(function(response) {
  		  		expect(response.value).toEqual("gotFactsDataFromSeevl");
  			}).error( function(response) {
  		  		expect(false).toEqual(true);
  			});

  		}));
  	});

  });

  describe('youtubeService test', function() {
  	it('.value should be "gotVideoFromYoutube', inject(function (youtubeService) {

  		youtubeService.search("nirvana").success(function(response) {
  			expect(response.value).toEqual("gotVideoFromYoutube");
  		}).error( function(response) {
  			expect(false).toEqual(true);
  		});

  	}));
  });

  describe('rottentomatoesFactory test', function() {
  	it('.value should be "gotMoviesFromRottenTomatoes', inject(function (rottentomatoesFactory) {

  		rottentomatoesFactory.getMovies().success(function(response) {
  			expect(response.value).toEqual("gotMoviesFromRottenTomatoes");
  		}).error( function(response) {
  			expect(false).toEqual(true);
  		});

  	}));
  });

  describe('bandsintownService test', function() {
  	it('.value should be "gotBandFromBandsInTown', inject(function (bandsintownService) {

  		bandsintownService.players("Skrillex").success(function(response) {
  			expect(response.value).toEqual("gotBandFromBandsInTown");
  		}).error( function(response) {
  			expect(false).toEqual(true);
  		});

  	}));
  });

});
<|endoftext|>


<commit_before>var express = require('express')
    , mongoose = require('mongoose')
    , UserImport = require('./lib/user-import')
    , UserImportSummary = require('./lib/user-import-summary')
    , dslogger = require('./lib/dslogger')
    ;
var mb_config = require(__dirname + '/config/mb_config.json');

/**
 * Initialize the logging mechanism. Defines filename to write to and whether
 * or not to also log to the console.
 */
dslogger.init('mb-logging-api-server', false);

/**
 * Parse command line arguments.
 *
 * -port -p
 *   Allows the caller to set the port that this app should run on.
 */
var listenForPort = false;
var overridePort = false;
var defaultPort = 4733;

process.argv.forEach(function(val, idx, arr) {
  if (listenForPort) {
    listenForPort = false;
    overridePort = parseInt(val);
  }

  if (val === '-port' || val === '-p') {
    listenForPort = true;
  }
});

/**
 * Express Setup
 */
var app = express();

app.configure(function() {

  // Replaces express.bodyParser() - parses request body and populates request.body
  app.use(express.urlencoded());
  app.use(express.json());

  // Checks request.body for HTTP method override
  app.use(express.methodOverride());

  // Perform route lookup based on url and HTTP method
  app.use(app.router);

  // catch 404 and forwarding to error handler
  app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
  });

});

/// error handlers

// development error handler
// will print stacktrace
/*
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.send(500, err.status);

    res.render('error', {
      message: err.message,
      error: err
    });

  });
  // Show all errors in development with express
  app.use(express.errorHandler({dumpException: true, showStack: true}));
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

*/

/**
 * Start server.
 */
var port = overridePort || process.env.MB_LOGGING_API_PORT || defaultPort;
app.listen(port, function() {
  console.log('Message Broker Logging API server listening on port %d in %s mode.', port, app.settings.env);
});

/**
 * Mongo setup and config.
 */
var mongoUri = mb_config.mongo;
mongoose.connect(mongoUri);
mongoose.connection.on('error', function(err) {
  console.log('Unable to connect to the Mongo database (%s). Check to make sure the database is running.', mongoUri);
  process.exit();
});

var userImportModel;
var userImportCollectionName_Niche = 'userimport-niche';
var userImportCollectionName_HerCampus = 'userimport-hercampus';
var userImportCollectionName_ATT_iChannel = 'userimport-att-ichannel';
var userImportCollectionName_TeenLife = 'userimport-teenlife';
var importSummaryModel;
var importSummaryCollectionName = 'import-summary';

mongoose.connection.once('open', function() {

  // User import logging schema for existing entries
  var userImportLoggingSchema = new mongoose.Schema({
    logged_date : { type: Date, default: Date.now },
    origin : {
      name : { type : String, trim : true },
      processed : { type: Date }
    },
    source : {
      type : String,
      lowercase : 1,
      trim : true,
      enum: ['niche', 'niche.com', 'hercampus', 'att-ichannel', 'teenlife']
    },
    phone : {
      number : { type : String, trim : true },
      status : { type : String, trim : true },
      acquired : { type: Date }
    },
    email : {
      address : { type : String, trim : true },
      status : { type : String, trim : true },
      acquired : { type: Date }
    },
    drupal : {
      email : { type : String, trim : true },
      uid : { type : Number }
    }
  });
  userImportLoggingSchema.set('autoIndex', false);
  // Logging model
  userImportModel_niche = mongoose.model(userImportCollectionName_Niche, userImportLoggingSchema);
  userImportModel_hercampus = mongoose.model(userImportCollectionName_HerCampus, userImportLoggingSchema);
  userImportModel_att_ichannel = mongoose.model(userImportCollectionName_ATT_iChannel, userImportLoggingSchema);
  userImportModel_teenlife = mongoose.model(userImportCollectionName_TeenLife, userImportLoggingSchema);

  // User import logging schema for summary reports
  var importSummarySchema = new mongoose.Schema({
    logged_date : { type: Date, default: Date.now },
    target_CSV_file : { type : String, trim : true },
    signup_count : { type : Number },
    skipped : { type : Number },
    source : {
      type : String,
      lowercase : 1,
      trim : true,
      enum: ['niche', 'niche.com', 'hercampus', 'att-ichannel', 'teenlife']
    },
    log_type : {
      type : String,
      lowercase : 1,
      trim : true,
      enum: ['user_import']
    },
  });
  importSummarySchema.set('autoIndex', false);
  // Logging summary model
  importSummaryModel = mongoose.model(importSummaryCollectionName, importSummarySchema);

  console.log("Connection to Mongo (%s) succeeded! Ready to go...\n\n", mongoUri);
});

/**
 * Routes
 */

/**
 * GET /api - report basic details about the API
 * GET /api/v1
 */
app.get('/api', function(req, res) {
  res.send(200, 'Message Broker Logging API (mb-logging-api). Available versions: v1 (/api/v1) See https://github.com/DoSomething/mb-logging-api for the related git repository.');
});
app.get('/api/v1', function(req, res) {
  res.send(200, 'Message Broker Logging API (mb-logging-api). Version 1.x.x, see wiki (https://github.com/DoSomething/mb-logging-api/wiki) for documentation');
});

/**
 * POST to /api/v1/imports
 *
 * @param type string
 *   ex. &type=user : The type of import, helps to define what collection the
 *   POST is added to.
 *
 * @param exists integer
 *   &exists=1 : Flag to log entries of existing Drupal, Mailchimp and Mobile
 *   Commons users in the userImportModel.
 *
 * @param source string
 *   &source=niche : Unique name to identify the source of the import data.
 */
app.post('/api/v1/imports', function(req, res) {
  if (req.query.type === undefined || req.query.exists === undefined || req.query.source === undefined || req.query.origin === undefined || req.query.processed_timestamp === undefined ||
      (req.body.email === undefined && req.body.phone === undefined && req.body.drupal_uid === undefined)) {
    res.send(400, 'Type, exists and source, origin or started_timestamp not specified or no email, phone or Drupal uid specified.');
    dslogger.error('POST /api/v1/imports request. No type, exists and source not specified or no email, phone or Drupal uid specified.');
  }
  else {

    // Use model based on source
    if (req.query.source.toLowerCase() === 'niche') {
      var userImport = new UserImport(userImportModel_niche);
      userImport.post(req, res);
    }
    else if (req.query.source.toLowerCase() === 'hercampus') {
      var userImport = new UserImport(userImportModel_hercampus);
      userImport.post(req, res);
    }
    else if (req.query.source.toLowerCase() === 'att-ichannel') {
      var userImport = new UserImport(userImportModel_att_ichannel);
      userImport.post(req, res);
    }
    else if (req.query.source.toLowerCase() === 'teenlife') {
      var userImport = new UserImport(userImportModel_teenlife);
      userImport.post(req, res);
    }
    else {
      console.log('POST /api/v1/imports request. Invalid source: ' + req.query.source);
      dslogger.error('POST /api/v1/imports request. Invalid source: ' + req.query.source);
    }
  }
});

/**
 * GET from /api/v1/imports/:start_timestamp/:end_timestamp
 */
app.get('/api/v1/imports/:start_date/:end_date', function(req, res) {
  var sd = new Date(req.param("start_date"));
  var ed = new Date(req.param("end_date"));
  if (sd != 'Invalid Date' && ed != 'Invalid Date') {
    if (req.query.type == 'user_import' && req.query.exists == 1 && req.query.source !== undefined) {
      var userImport = new UserImport(userImportModel);
      userImport.get(req, res);
    }
    else {
      res.send(400, 'type or exists setting specified not supported at this time.');
      dslogger.error('GET /api/v1/imports request. type or exists setting specified not supported at this time.');
    }
  }
  else {
    res.send(400, 'Validation error: /api/v1/imports/:start_date/:end_date -> Invalid start or end dates.');
    dslogger.error('GET /api/v1/imports/:start_date/:end_date request. Invalid start or end dates.');
  }
});

/**
 * POST to /api/v1/imports/summaries
 *
 * @param type string
 *   ex. &type=user : The type of import.
 *
 * @param source string
 *   &source=niche.com : Unique name to identify the source of the import data.
 */
app.post('/api/v1/imports/summaries', function(req, res) {
  if (req.query.type === undefined || req.query.source === undefined ||
      req.body.target_CSV_file === undefined || req.body.signup_count === undefined || req.body.skipped === undefined) {
    res.send(400, 'Type or source not specified or no target CSV file, signup count and skipped values specified.');
    dslogger.error('POST /api/v1/imports/summaries request. Type or source not specified or no target CSV file, signup count and skipped values specified.');
  }
  else {
    var userImportSummary = new UserImportSummary(importSummaryModel);
    userImportSummary.post(req, res);
  }
});

/**
 * GET from /api/v1/imports/summaries/:start_timestamp/:end_timestamp
 */
app.get('/api/v1/imports/summaries/:start_date/:end_date', function(req, res) {
  var sd = new Date(req.param("start_date"));
  var ed = new Date(req.param("end_date"));
  if (sd != 'Invalid Date' && ed != 'Invalid Date') {
    if (req.query.type == 'user_import' && req.query.exists == 1) {
      var userImportSummary = new UserImportSummary(importSummaryModel);
      userImportSummary.get(req, res);
    }
    else {
      res.send(400, 'type or exists setting specified not supported at this time.');
      dslogger.error('GET /api/v1/imports/summaries/:start_date/:end_date request. type or exists setting specified not supported at this time.');
    }
  }
  else {
    res.send(400, 'Validation error: /api/v1/imports/summaries/:start_date/:end_date -> Invalid start or end dates.');
    dslogger.error('GET /api/v1/imports/summaries/:start_date/:end_date request. Invalid start or end dates.');
  }
});
<commit_msg>Adds schema definition for UserEvent<commit_after>var express = require('express')
    , mongoose = require('mongoose')
    , UserImport = require('./lib/user-import')
    , UserImportSummary = require('./lib/user-import-summary')
    , dslogger = require('./lib/dslogger')
    ;
var mb_config = require(__dirname + '/config/mb_config.json');

/**
 * Initialize the logging mechanism. Defines filename to write to and whether
 * or not to also log to the console.
 */
dslogger.init('mb-logging-api-server', false);

/**
 * Parse command line arguments.
 *
 * -port -p
 *   Allows the caller to set the port that this app should run on.
 */
var listenForPort = false;
var overridePort = false;
var defaultPort = 4733;

process.argv.forEach(function(val, idx, arr) {
  if (listenForPort) {
    listenForPort = false;
    overridePort = parseInt(val);
  }

  if (val === '-port' || val === '-p') {
    listenForPort = true;
  }
});

/**
 * Express Setup
 */
var app = express();

app.configure(function() {

  // Replaces express.bodyParser() - parses request body and populates request.body
  app.use(express.urlencoded());
  app.use(express.json());

  // Checks request.body for HTTP method override
  app.use(express.methodOverride());

  // Perform route lookup based on url and HTTP method
  app.use(app.router);

  // catch 404 and forwarding to error handler
  app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
  });

});

/// error handlers

// development error handler
// will print stacktrace
/*
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.send(500, err.status);

    res.render('error', {
      message: err.message,
      error: err
    });

  });
  // Show all errors in development with express
  app.use(express.errorHandler({dumpException: true, showStack: true}));
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

*/

/**
 * Start server.
 */
var port = overridePort || process.env.MB_LOGGING_API_PORT || defaultPort;
app.listen(port, function() {
  console.log('Message Broker Logging API server listening on port %d in %s mode.', port, app.settings.env);
});

/**
 * Mongo setup and config.
 */
var mongoUri = mb_config.mongo;
mongoose.connect(mongoUri);
mongoose.connection.on('error', function(err) {
  console.log('Unable to connect to the Mongo database (%s). Check to make sure the database is running.', mongoUri);
  process.exit();
});

var userImportModel;
var userImportCollectionName_Niche = 'userimport-niche';
var userImportCollectionName_HerCampus = 'userimport-hercampus';
var userImportCollectionName_ATT_iChannel = 'userimport-att-ichannel';
var userImportCollectionName_TeenLife = 'userimport-teenlife';
var importSummaryModel;
var importSummaryCollectionName = 'import-summary';

var externalApplicationUserEventModel;
var externalApplicationUserEventCollectionName = 'externalapplicationuserevent';

mongoose.connection.once('open', function() {

  // User import logging schema for existing entries
  var userImportLoggingSchema = new mongoose.Schema({
    logged_date : { type: Date, default: Date.now },
    origin : {
      name : { type : String, trim : true },
      processed : { type: Date }
    },
    source : {
      type : String,
      lowercase : 1,
      trim : true,
      enum: ['niche', 'niche.com', 'hercampus', 'att-ichannel', 'teenlife']
    },
    phone : {
      number : { type : String, trim : true },
      status : { type : String, trim : true },
      acquired : { type: Date }
    },
    email : {
      address : { type : String, trim : true },
      status : { type : String, trim : true },
      acquired : { type: Date }
    },
    drupal : {
      email : { type : String, trim : true },
      uid : { type : Number }
    }
  });
  userImportLoggingSchema.set('autoIndex', false);
  // Logging model
  userImportModel_niche = mongoose.model(userImportCollectionName_Niche, userImportLoggingSchema);
  userImportModel_hercampus = mongoose.model(userImportCollectionName_HerCampus, userImportLoggingSchema);
  userImportModel_att_ichannel = mongoose.model(userImportCollectionName_ATT_iChannel, userImportLoggingSchema);
  userImportModel_teenlife = mongoose.model(userImportCollectionName_TeenLife, userImportLoggingSchema);

  // User import logging schema for summary reports
  var importSummarySchema = new mongoose.Schema({
    logged_date : { type: Date, default: Date.now },
    target_CSV_file : { type : String, trim : true },
    signup_count : { type : Number },
    skipped : { type : Number },
    source : {
      type : String,
      lowercase : 1,
      trim : true,
      enum: ['niche', 'niche.com', 'hercampus', 'att-ichannel', 'teenlife']
    },
    log_type : {
      type : String,
      lowercase : 1,
      trim : true,
      enum: ['user_import']
    },
  });
  importSummarySchema.set('autoIndex', false);
  // Logging summary model
  importSummaryModel = mongoose.model(importSummaryCollectionName, importSummarySchema);

  // External application user event logging schema for "in the future" email list generation
  var externalApplicationUserEventSchema = new mongoose.Schema({
    logged_date : { type: Date, default: Date.now },
    email : { type : String, trim : true },
    source : {
      type : String,
      lowercase : 0,
      trim : true,
      enum: ['CGG', 'AGG']
    },
    activity : {
      type : String,
      lowercase : 1,
      trim : true,
      enum: ['vote']
    },
    activity_date : { type: Date, default: Date.now },
    activity_timestamp : { type : Number },
    activity_details : { type : String }
  });
  externalApplicationUserEventSchema.set('autoIndex', false);
  // Logging summary model
  externalApplicationUserEventModel = mongoose.model(externalApplicationUserEventCollectionName, externalApplicationUserEventSchema);

  console.log("Connection to Mongo (%s) succeeded! Ready to go...\n\n", mongoUri);
});

/**
 * Routes
 */

/**
 * GET /api - report basic details about the API
 * GET /api/v1
 */
app.get('/api', function(req, res) {
  res.send(200, 'Message Broker Logging API (mb-logging-api). Available versions: v1 (/api/v1) See https://github.com/DoSomething/mb-logging-api for the related git repository.');
});
app.get('/api/v1', function(req, res) {
  res.send(200, 'Message Broker Logging API (mb-logging-api). Version 1.x.x, see wiki (https://github.com/DoSomething/mb-logging-api/wiki) for documentation');
});

/**
 * POST to /api/v1/imports
 *
 * @param type string
 *   ex. &type=user : The type of import, helps to define what collection the
 *   POST is added to.
 *
 * @param exists integer
 *   &exists=1 : Flag to log entries of existing Drupal, Mailchimp and Mobile
 *   Commons users in the userImportModel.
 *
 * @param source string
 *   &source=niche : Unique name to identify the source of the import data.
 */
app.post('/api/v1/imports', function(req, res) {
  if (req.query.type === undefined || req.query.exists === undefined || req.query.source === undefined || req.query.origin === undefined || req.query.processed_timestamp === undefined ||
      (req.body.email === undefined && req.body.phone === undefined && req.body.drupal_uid === undefined)) {
    res.send(400, 'Type, exists and source, origin or started_timestamp not specified or no email, phone or Drupal uid specified.');
    dslogger.error('POST /api/v1/imports request. No type, exists and source not specified or no email, phone or Drupal uid specified.');
  }
  else {

    // Use model based on source
    if (req.query.source.toLowerCase() === 'niche') {
      var userImport = new UserImport(userImportModel_niche);
      userImport.post(req, res);
    }
    else if (req.query.source.toLowerCase() === 'hercampus') {
      var userImport = new UserImport(userImportModel_hercampus);
      userImport.post(req, res);
    }
    else if (req.query.source.toLowerCase() === 'att-ichannel') {
      var userImport = new UserImport(userImportModel_att_ichannel);
      userImport.post(req, res);
    }
    else if (req.query.source.toLowerCase() === 'teenlife') {
      var userImport = new UserImport(userImportModel_teenlife);
      userImport.post(req, res);
    }
    else {
      console.log('POST /api/v1/imports request. Invalid source: ' + req.query.source);
      dslogger.error('POST /api/v1/imports request. Invalid source: ' + req.query.source);
    }
  }
});

/**
 * GET from /api/v1/imports/:start_timestamp/:end_timestamp
 */
app.get('/api/v1/imports/:start_date/:end_date', function(req, res) {
  var sd = new Date(req.param("start_date"));
  var ed = new Date(req.param("end_date"));
  if (sd != 'Invalid Date' && ed != 'Invalid Date') {
    if (req.query.type == 'user_import' && req.query.exists == 1 && req.query.source !== undefined) {
      var userImport = new UserImport(userImportModel);
      userImport.get(req, res);
    }
    else {
      res.send(400, 'type or exists setting specified not supported at this time.');
      dslogger.error('GET /api/v1/imports request. type or exists setting specified not supported at this time.');
    }
  }
  else {
    res.send(400, 'Validation error: /api/v1/imports/:start_date/:end_date -> Invalid start or end dates.');
    dslogger.error('GET /api/v1/imports/:start_date/:end_date request. Invalid start or end dates.');
  }
});

/**
 * POST to /api/v1/imports/summaries
 *
 * @param type string
 *   ex. &type=user : The type of import.
 *
 * @param source string
 *   &source=niche.com : Unique name to identify the source of the import data.
 */
app.post('/api/v1/imports/summaries', function(req, res) {
  if (req.query.type === undefined || req.query.source === undefined ||
      req.body.target_CSV_file === undefined || req.body.signup_count === undefined || req.body.skipped === undefined) {
    res.send(400, 'Type or source not specified or no target CSV file, signup count and skipped values specified.');
    dslogger.error('POST /api/v1/imports/summaries request. Type or source not specified or no target CSV file, signup count and skipped values specified.');
  }
  else {
    var userImportSummary = new UserImportSummary(importSummaryModel);
    userImportSummary.post(req, res);
  }
});

/**
 * GET from /api/v1/imports/summaries/:start_timestamp/:end_timestamp
 */
app.get('/api/v1/imports/summaries/:start_date/:end_date', function(req, res) {
  var sd = new Date(req.param("start_date"));
  var ed = new Date(req.param("end_date"));
  if (sd != 'Invalid Date' && ed != 'Invalid Date') {
    if (req.query.type == 'user_import' && req.query.exists == 1) {
      var userImportSummary = new UserImportSummary(importSummaryModel);
      userImportSummary.get(req, res);
    }
    else {
      res.send(400, 'type or exists setting specified not supported at this time.');
      dslogger.error('GET /api/v1/imports/summaries/:start_date/:end_date request. type or exists setting specified not supported at this time.');
    }
  }
  else {
    res.send(400, 'Validation error: /api/v1/imports/summaries/:start_date/:end_date -> Invalid start or end dates.');
    dslogger.error('GET /api/v1/imports/summaries/:start_date/:end_date request. Invalid start or end dates.');
  }
});
<|endoftext|>


<commit_before>/* global Promise */

var http = require('http');
var assert = require('chai').assert;
var proxyquire = require('proxyquire');
var sinon = require('sinon');
var nop = require('nop');
var getRandomPort = require('get-random-port');
var systemUnderTest = require('../../dist/adapter');
var SlackMessageAdapter = systemUnderTest.default;

// fixtures
var workingVerificationToken = 'VERIFICATION_TOKEN';

// helpers
/**
 * Encapsulates knowledge of adapter handler registration internals and asserts that a handler
 * was registered.
 *
 * @param {SlackMessageAdapter} adapter
 * @param {Function} handler
 * @param {Object} [constraints]
 */
function assertHandlerRegistered(adapter, handler, constraints) {
  var callbackEntry;

  assert.isNotEmpty(adapter.callbacks);
  callbackEntry = adapter.callbacks.find(function (aCallbackEntry) {
    return handler === aCallbackEntry[1];
  });
  assert.isOk(callbackEntry);
  if (constraints) {
    assert.deepEqual(callbackEntry[0], constraints);
  }
}

/**
 * Encapsulates knowledge of adapter handler registration internals and unregistered all handlers.
 * @param {SlackMessageAdapter} adapter
 */
function unregisterAllHandlers(adapter) {
  adapter.callbacks = []; // eslint-disable-line no-param-reassign
}

// shared tests
function shouldRegisterWithCallbackId(methodName) {
  describe('when registering with a callback_id', function () {
    beforeEach(function () {
      this.handler = function () { };
    });
    it('a plain string callback_id registers successfully', function () {
      this.adapter[methodName]('my_callback', this.handler);
      assertHandlerRegistered(this.adapter, this.handler);
    });
    it('a RegExp callback_id registers successfully', function () {
      this.adapter[methodName](/\w+_callback/, this.handler);
      assertHandlerRegistered(this.adapter, this.handler);
    });
    it('invalid callback_id types throw on registration', function () {
      var handler = this.handler;
      assert.throws(function () {
        this.adapter[methodName](5, handler);
      }, TypeError);
      assert.throws(function () {
        this.adapter[methodName](true, handler);
      }, TypeError);
      assert.throws(function () {
        this.adapter[methodName]([], handler);
      }, TypeError);
      assert.throws(function () {
        this.adapter[methodName](null, handler);
      }, TypeError);
      assert.throws(function () {
        this.adapter[methodName](undefined, handler);
      }, TypeError);
    });
  });
}

// test suite
describe('SlackMessageAdapter', function () {
  beforeEach(function () {
  });
  describe('constructor', function () {
    it('should build an instance', function () {
      var adapter = new SlackMessageAdapter(workingVerificationToken);
      assert.instanceOf(adapter, SlackMessageAdapter);
    });
    it('should fail without a verification token', function () {
      assert.throws(function () {
        var adapter = new SlackMessageAdapter();  // eslint-disable-line no-unused-vars
      }, TypeError);
    });
  });

  describe('#createServer()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    describe('when express package is not found', function () {
      beforeEach(function () {
        var SlackMessageAdapterNoExpress = proxyquire('../../dist/adapter', { express: null }).default;
        this.adapter = new SlackMessageAdapterNoExpress(workingVerificationToken);
      });
      it('should reject', function () {
        return this.adapter.createServer()
          .then(function (server) {
            assert.isNotOk(server, 'a server was created');
          })
          .catch(function (error) {
            if (error.code === 'MODULE_NOT_FOUND') {
              assert(true);
            } else {
              throw error;
            }
          });
      });
    });

    describe('when body-parser package is not found', function () {
      beforeEach(function () {
        var SlackMessageAdapterNoBodyParser = proxyquire('../../dist/adapter', { 'body-parser': null }).default;
        this.adapter = new SlackMessageAdapterNoBodyParser(workingVerificationToken);
      });
      it('should reject', function () {
        return this.adapter.createServer()
          .then(function (server) {
            assert.isNotOk(server, 'a server was created');
          })
          .catch(function (error) {
            if (error.code === 'MODULE_NOT_FOUND') {
              assert(true);
            } else {
              throw error;
            }
          });
      });
    });

    it('should return a Promise of an http.Server', function () {
      return this.adapter.createServer().then(function (server) {
        assert.instanceOf(server, http.Server);
      });
    });
  });

  describe('#start()', function () {
    beforeEach(function (done) {
      var self = this;
      self.adapter = new SlackMessageAdapter(workingVerificationToken);
      getRandomPort(function (error, port) {
        if (error) return done(error);
        self.portNumber = port;
        return done();
      });
    });
    afterEach(function () {
      return this.adapter.stop().catch(nop);
    });
    it('should return a Promise for a started http.Server', function () {
      var self = this;
      return this.adapter.start(self.portNumber).then(function (server) {
        // only works in node >= 5.7.0
        // assert(server.listening);
        assert.equal(server.address().port, self.portNumber);
      });
    });
  });

  describe('#stop()', function () {
    beforeEach(function (done) {
      var self = this;
      self.adapter = new SlackMessageAdapter(workingVerificationToken);
      getRandomPort(function (error, port) {
        if (error) return done(error);
        return self.adapter.start(port)
          .then(function (server) {
            self.server = server;
            done();
          })
          .catch(done);
      });
    });
    afterEach(function () {
      return this.adapter.stop().catch(nop);
    });
    it('should return a Promise and the server should be stopped', function () {
      var self = this;
      return this.adapter.stop().then(function () {
        assert(!self.server.listening);
      });
    });
  });

  describe('#expressMiddleware()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    it('should return a function', function () {
      var middleware = this.adapter.expressMiddleware();
      assert.isFunction(middleware);
    });
  });

  describe('#action()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    it('should fail action registration without handler', function () {
      assert.throws(function () {
        this.adapter.action('my_callback');
      }, TypeError);
    });

    // shared tests
    shouldRegisterWithCallbackId('action');

    describe('when registering with a complex set of constraints', function () {
      beforeEach(function () {
        this.actionHandler = function () { };
      });
      it('should register with valid type constraints successfully', function () {
        var adapter = this.adapter;
        var actionHandler = this.actionHandler;
        var constraintsSet = [
          { type: 'button' },
          { type: 'select' },
          { type: 'dialog_submission' }
        ];
        constraintsSet.forEach(function (constraints) {
          adapter.action(constraints, actionHandler);
          assertHandlerRegistered(adapter, actionHandler, constraints);
          unregisterAllHandlers(adapter);
        });
      });
      it('should throw when registering with invalid type constraints', function () {
        var actionHandler = this.actionHandler;
        var constraints = { type: 'not_a_real_action_type' };
        assert.throws(function () {
          this.adapter.action(constraints, actionHandler);
        }, TypeError);
      });
      it('should register with valid compound constraints successfully', function () {
        var constraints = { callbackId: 'my_callback', type: 'button' };
        this.adapter.action(constraints, this.actionHandler);
        assertHandlerRegistered(this.adapter, this.actionHandler, constraints);
      });
      it('should throw when registering with invalid compound constraints', function () {
        var actionHandler = this.actionHandler;
        var constraints = { callbackId: /\w+_callback/, type: 'not_a_real_action_type' };
        assert.throws(function () {
          this.adapter.action(constraints, actionHandler);
        }, TypeError);
      });
      it('should register with unfurl constraint successfully', function () {
        var constraints = { unfurl: true };
        this.adapter.action(constraints, this.actionHandler);
        assertHandlerRegistered(this.adapter, this.actionHandler, constraints);
      });
    });
  });

  describe('#options()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    it('should fail options registration without handler', function () {
      assert.throws(function () {
        this.adapter.options('my_callback');
      }, TypeError);
    });

    // shared tests
    shouldRegisterWithCallbackId('options');
  });

  describe('#dispatch()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
      this.synchronousTimeout = 2500;
    });
    // NOTE: the middleware has to check the verification token, poweredBy headers
    describe('when dispatching an message action request', function () {
      it('should handle the callback returning a message with a synchronous response', function () {
        var dispatchResponse;
        var requestPayload = {
          type: 'interactive_message',
          callback_id: 'id',
          text: 'example input message',
          response_url: 'https://example.com'
        };
        var replacement = { text: 'example replacement message' };
        this.adapter.action('id', function (payload, respond) {
          assert.deepEqual(payload, requestPayload);
          assert.isFunction(respond);
          return replacement;
        });
        dispatchResponse = this.adapter.dispatch(requestPayload);
        assert.equal(dispatchResponse.status, 200);
        return Promise.resolve(dispatchResponse.content)
          .then(function (content) {
            assert.deepEqual(content, replacement);
          });
      });
      it('should handle the callback returning a promise of a message before the timeout with a ' +
         'synchronous response', function () {
        var dispatchResponse;
        var requestPayload = {
          type: 'interactive_message',
          callback_id: 'id',
          text: 'example input message',
          response_url: 'https://example.com'
        };
        var replacement = { text: 'example replacement message' };
        var timeout = this.synchronousTimeout;
        this.timeout(timeout);
        this.adapter.action('id', function (payload, respond) {
          assert.deepEqual(payload, requestPayload);
          assert.isFunction(respond);
          return new Promise(function (resolve) {
            setTimeout(function () {
              resolve(replacement);
            }, timeout / 2);
          });
        });
        dispatchResponse = this.adapter.dispatch(requestPayload);
        assert.equal(dispatchResponse.status, 200);
        return Promise.resolve(dispatchResponse.content)
          .then(function (content) {
            assert.deepEqual(content, replacement);
          });
      });
      it('should handle the callback returning a promise of a message after the timeout with an ' +
         'asynchronous response', function () {
        var dispatchResponse;
        var expectedSyncResponse;
        var expectedAsyncRequest;
        var requestPayload = {
          type: 'interactive_message',
          callback_id: 'id',
          text: 'example input message',
          response_url: 'https://example.com'
        };
        var replacement = { text: 'example replacement message' };
        var timeout = this.synchronousTimeout;
        var adapter = this.adapter;
        expectedAsyncRequest = new Promise(function (resolve, reject) {
          sinon.stub(adapter.axios, 'post').callsFake(function (url, body) {
            try {
              assert.equal(url, requestPayload.response_url);
              assert.deepEqual(body, replacement);
              resolve();
            } catch (error) {
              reject(error);
            }
          });
        });
        this.timeout(timeout * 1.5);
        this.adapter.action('id', function (payload, respond) {
          assert.deepEqual(payload, requestPayload);
          assert.isFunction(respond);
          return new Promise(function (resolve) {
            setTimeout(function () {
              resolve(replacement);
            }, timeout + 20);
          });
        });
        dispatchResponse = this.adapter.dispatch(requestPayload);
        assert.equal(dispatchResponse.status, 200);
        expectedSyncResponse = Promise.resolve(dispatchResponse.content)
          .then(function (content) {
            assert.deepEqual(content, '');
          });
        return Promise.all([expectedSyncResponse, expectedAsyncRequest]);
      });
    });
  });
});
<commit_msg>refactors reused code into helpers and implements another async test for message action dispatch<commit_after>/* global Promise */

var http = require('http');
var assert = require('chai').assert;
var proxyquire = require('proxyquire');
var sinon = require('sinon');
var nop = require('nop');
var getRandomPort = require('get-random-port');
var systemUnderTest = require('../../dist/adapter');
var SlackMessageAdapter = systemUnderTest.default;

// fixtures
var workingVerificationToken = 'VERIFICATION_TOKEN';

// helpers
function delayed(ms, value, rejectionReason) {
  var error;
  if (rejectionReason) {
    error = new Error(rejectionReason);
  }
  return new Promise(function (resolve, reject) {
    var id = setTimeout(function () {
      clearTimeout(id);
      if (error) {
        reject(error);
      } else {
        resolve(value);
      }
    }, ms);
  });
}

// test suite
describe('SlackMessageAdapter', function () {
  describe('constructor', function () {
    it('should build an instance', function () {
      var adapter = new SlackMessageAdapter(workingVerificationToken);
      assert.instanceOf(adapter, SlackMessageAdapter);
    });
    it('should fail without a verification token', function () {
      assert.throws(function () {
        var adapter = new SlackMessageAdapter();  // eslint-disable-line no-unused-vars
      }, TypeError);
    });
  });

  describe('#createServer()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    describe('when express package is not found', function () {
      beforeEach(function () {
        var SlackMessageAdapterNoExpress = proxyquire('../../dist/adapter', { express: null }).default;
        this.adapter = new SlackMessageAdapterNoExpress(workingVerificationToken);
      });
      it('should reject', function () {
        return this.adapter.createServer()
          .then(function (server) {
            assert.isNotOk(server, 'a server was created');
          })
          .catch(function (error) {
            if (error.code === 'MODULE_NOT_FOUND') {
              assert(true);
            } else {
              throw error;
            }
          });
      });
    });

    describe('when body-parser package is not found', function () {
      beforeEach(function () {
        var SlackMessageAdapterNoBodyParser = proxyquire('../../dist/adapter', { 'body-parser': null }).default;
        this.adapter = new SlackMessageAdapterNoBodyParser(workingVerificationToken);
      });
      it('should reject', function () {
        return this.adapter.createServer()
          .then(function (server) {
            assert.isNotOk(server, 'a server was created');
          })
          .catch(function (error) {
            if (error.code === 'MODULE_NOT_FOUND') {
              assert(true);
            } else {
              throw error;
            }
          });
      });
    });

    it('should return a Promise of an http.Server', function () {
      return this.adapter.createServer().then(function (server) {
        assert.instanceOf(server, http.Server);
      });
    });
  });

  describe('#start()', function () {
    beforeEach(function (done) {
      var self = this;
      self.adapter = new SlackMessageAdapter(workingVerificationToken);
      getRandomPort(function (error, port) {
        if (error) return done(error);
        self.portNumber = port;
        return done();
      });
    });
    afterEach(function () {
      return this.adapter.stop().catch(nop);
    });
    it('should return a Promise for a started http.Server', function () {
      var self = this;
      return this.adapter.start(self.portNumber).then(function (server) {
        // only works in node >= 5.7.0
        // assert(server.listening);
        assert.equal(server.address().port, self.portNumber);
      });
    });
  });

  describe('#stop()', function () {
    beforeEach(function (done) {
      var self = this;
      self.adapter = new SlackMessageAdapter(workingVerificationToken);
      getRandomPort(function (error, port) {
        if (error) return done(error);
        return self.adapter.start(port)
          .then(function (server) {
            self.server = server;
            done();
          })
          .catch(done);
      });
    });
    afterEach(function () {
      return this.adapter.stop().catch(nop);
    });
    it('should return a Promise and the server should be stopped', function () {
      var self = this;
      return this.adapter.stop().then(function () {
        assert(!self.server.listening);
      });
    });
  });

  describe('#expressMiddleware()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    it('should return a function', function () {
      var middleware = this.adapter.expressMiddleware();
      assert.isFunction(middleware);
    });
  });

  // helpers
  /**
   * Encapsulates knowledge of adapter handler registration internals and asserts that a handler
   * was registered.
   *
   * @param {SlackMessageAdapter} adapter actual instance where handler should be registered
   * @param {Function} handler expected registered function
   * @param {Object} [constraints] expected constraints for which handler should be registered
   */
  function assertHandlerRegistered(adapter, handler, constraints) {
    var callbackEntry;

    assert.isNotEmpty(adapter.callbacks);
    callbackEntry = adapter.callbacks.find(function (aCallbackEntry) {
      return handler === aCallbackEntry[1];
    });
    assert.isOk(callbackEntry);
    if (constraints) {
      assert.deepEqual(callbackEntry[0], constraints);
    }
  }

  /**
   * Encapsulates knowledge of adapter handler registration internals and unregistered all handlers.
   * @param {SlackMessageAdapter} adapter
   */
  function unregisterAllHandlers(adapter) {
    adapter.callbacks = []; // eslint-disable-line no-param-reassign
  }

  // shared tests
  function shouldRegisterWithCallbackId(methodName) {
    describe('when registering with a callback_id', function () {
      beforeEach(function () {
        this.handler = function () { };
      });
      it('a plain string callback_id registers successfully', function () {
        this.adapter[methodName]('my_callback', this.handler);
        assertHandlerRegistered(this.adapter, this.handler);
      });
      it('a RegExp callback_id registers successfully', function () {
        this.adapter[methodName](/\w+_callback/, this.handler);
        assertHandlerRegistered(this.adapter, this.handler);
      });
      it('invalid callback_id types throw on registration', function () {
        var handler = this.handler;
        assert.throws(function () {
          this.adapter[methodName](5, handler);
        }, TypeError);
        assert.throws(function () {
          this.adapter[methodName](true, handler);
        }, TypeError);
        assert.throws(function () {
          this.adapter[methodName]([], handler);
        }, TypeError);
        assert.throws(function () {
          this.adapter[methodName](null, handler);
        }, TypeError);
        assert.throws(function () {
          this.adapter[methodName](undefined, handler);
        }, TypeError);
      });
    });
  }

  describe('#action()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    it('should fail action registration without handler', function () {
      assert.throws(function () {
        this.adapter.action('my_callback');
      }, TypeError);
    });

    // execute shared tests
    shouldRegisterWithCallbackId('action');

    describe('when registering with a complex set of constraints', function () {
      beforeEach(function () {
        this.actionHandler = function () { };
      });
      it('should register with valid type constraints successfully', function () {
        var adapter = this.adapter;
        var actionHandler = this.actionHandler;
        var constraintsSet = [
          { type: 'button' },
          { type: 'select' },
          { type: 'dialog_submission' }
        ];
        constraintsSet.forEach(function (constraints) {
          adapter.action(constraints, actionHandler);
          assertHandlerRegistered(adapter, actionHandler, constraints);
          unregisterAllHandlers(adapter);
        });
      });
      it('should throw when registering with invalid type constraints', function () {
        var actionHandler = this.actionHandler;
        var constraints = { type: 'not_a_real_action_type' };
        assert.throws(function () {
          this.adapter.action(constraints, actionHandler);
        }, TypeError);
      });
      it('should register with valid compound constraints successfully', function () {
        var constraints = { callbackId: 'my_callback', type: 'button' };
        this.adapter.action(constraints, this.actionHandler);
        assertHandlerRegistered(this.adapter, this.actionHandler, constraints);
      });
      it('should throw when registering with invalid compound constraints', function () {
        var actionHandler = this.actionHandler;
        var constraints = { callbackId: /\w+_callback/, type: 'not_a_real_action_type' };
        assert.throws(function () {
          this.adapter.action(constraints, actionHandler);
        }, TypeError);
      });
      it('should register with unfurl constraint successfully', function () {
        var constraints = { unfurl: true };
        this.adapter.action(constraints, this.actionHandler);
        assertHandlerRegistered(this.adapter, this.actionHandler, constraints);
      });
    });
  });

  describe('#options()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
    });
    it('should fail options registration without handler', function () {
      assert.throws(function () {
        this.adapter.options('my_callback');
      }, TypeError);
    });

    // execute shared tests
    shouldRegisterWithCallbackId('options');
  });

  describe('#dispatch()', function () {
    beforeEach(function () {
      this.adapter = new SlackMessageAdapter(workingVerificationToken);
      this.synchronousTimeout = 2500;
    });

    /**
     * Assert the result of a dispatch contains a certain message
     * @param {Object} response actual return value of adapter.dispatch (synchronous reponse)
     * @param {Object|string|undefined} message expected value of response body
     * @returns {Promise<void>}
     */
    function assertResponseContainsMessage(response, message) {
      return Promise.resolve(response.content)
        .then(function (content) {
          assert.deepEqual(content, message);
        });
    }

    /**
     * Encapsulates knowledge of how the adapter makes post requests by arranging a stub that can
     * observe these requests and verify that one is made to the given url with the given message.
     * @param {SlackMessageAdapter} adapter actual adapter
     * @param {string} requestUrl expected request URL
     * @param {Object|string} message expected message in request body
     */
    function assertPostRequestMadeWithMessage(adapter, requestUrl, message) {
      return new Promise(function (resolve, reject) {
        sinon.stub(adapter.axios, 'post').callsFake(function (url, body) {
          try {
            assert.equal(url, requestUrl);
            assert.deepEqual(body, message);
            resolve();
          } catch (error) {
            reject(error);
          }
        });
      });
    }

    // NOTE: the middleware has to check the verification token, poweredBy headers
    describe('when dispatching an message action request', function () {
      beforeEach(function () {
        this.requestPayload = {
          type: 'interactive_message',
          callback_id: 'id',
          actions: [{}],
          response_url: 'https://example.com'
        };
        this.replacement = { text: 'example replacement message' };
      });
      it('should handle the callback returning a message with a synchronous response', function () {
        var dispatchResponse;
        var requestPayload = this.requestPayload;
        var replacement = this.replacement;
        this.adapter.action(requestPayload.callback_id, function (payload, respond) {
          assert.deepEqual(payload, requestPayload);
          assert.isFunction(respond);
          return replacement;
        });
        dispatchResponse = this.adapter.dispatch(requestPayload);
        assert.equal(dispatchResponse.status, 200);
        return assertResponseContainsMessage(dispatchResponse, replacement);
      });
      it('should handle the callback returning a promise of a message before the timeout with a ' +
         'synchronous response', function () {
        var dispatchResponse;
        var requestPayload = this.requestPayload;
        var replacement = this.replacement;
        var timeout = this.synchronousTimeout;
        this.timeout(timeout);
        this.adapter.action(requestPayload.callback_id, function (payload, respond) {
          assert.deepEqual(payload, requestPayload);
          assert.isFunction(respond);
          return delayed(timeout * 0.1, replacement);
        });
        dispatchResponse = this.adapter.dispatch(requestPayload);
        assert.equal(dispatchResponse.status, 200);
        return assertResponseContainsMessage(dispatchResponse, replacement);
      });
      it('should handle the callback returning a promise of a message after the timeout with an ' +
         'asynchronous response', function () {
        var dispatchResponse;
        var requestPayload = this.requestPayload;
        var replacement = this.replacement;
        var expectedAsyncRequest = assertPostRequestMadeWithMessage(
          this.adapter,
          requestPayload.response_url,
          replacement
        );
        var timeout = this.synchronousTimeout;
        this.timeout(timeout * 1.5);
        this.adapter.action(requestPayload.callback_id, function (payload, respond) {
          assert.deepEqual(payload, requestPayload);
          assert.isFunction(respond);
          return delayed(timeout + 20, replacement);
        });
        dispatchResponse = this.adapter.dispatch(requestPayload);
        assert.equal(dispatchResponse.status, 200);
        return Promise.all([
          assertResponseContainsMessage(dispatchResponse, ''),
          expectedAsyncRequest
        ]);
      });
      it('should handle the callback returning nothing and using respond to send a message', function () {
        var dispatchResponse;
        var requestPayload = this.requestPayload;
        var replacement = this.replacement;
        var expectedAsyncRequest = assertPostRequestMadeWithMessage(
          this.adapter,
          requestPayload.response_url,
          replacement
        );
        this.adapter.action(requestPayload.callback_id, function (payload, respond) {
          respond(replacement);
        });
        dispatchResponse = this.adapter.dispatch(requestPayload);
        assert.equal(dispatchResponse.status, 200);
        return Promise.all([
          assertResponseContainsMessage(dispatchResponse, ''),
          expectedAsyncRequest
        ]);
      });
      // TODO: multiple calls to respond
    });
  });
});
<|endoftext|>


<commit_before>/**
 * @fileOverview The dependency task test.
 */

var tasks  = require('../../tasks/grunt_tasks')(),
    cTools = require('grunt-closure-tools')(),
    sinon  = require('sinon'),
    expect = require('chai').expect,
    grunt  = require('grunt'),
    assert = require('chai').assert;

var tmp = 'temp/';
var fixtures = 'test/expected/';

describe('Grunt task :: dependency', function(){

  beforeEach(function() {
  });

  afterEach(function() {
  });

  it('produce the proper result', function(){

    var actualFile = 'deps.js';
    var actual = grunt.file.read(tmp + actualFile);
    var expected = grunt.file.read(fixtures + actualFile);

    // cheat a little, first line is the depsWriter.py full path declaration.
    // this breaks tests in each different setup.
    //
    // so, remove first line from both files
    actual = actual.split('\n').splice(0,1).join('\n');
    expected = expected.split('\n').splice(0,1).join('\n');

    assert.equal(actual, expected, 'task output should equal: ' + actualFile);

  });
});
<commit_msg>uh duh<commit_after>/**
 * @fileOverview The dependency task test.
 */

var tasks  = require('../../tasks/grunt_tasks')(),
    cTools = require('grunt-closure-tools')(),
    sinon  = require('sinon'),
    expect = require('chai').expect,
    grunt  = require('grunt'),
    assert = require('chai').assert;

var tmp = 'temp/';
var fixtures = 'test/expected/';

describe('Grunt task :: dependency', function(){

  beforeEach(function() {
  });

  afterEach(function() {
  });

  it('produce the proper result', function(){

    var actualFile = 'deps.js';
    var actual = grunt.file.read(tmp + actualFile);
    var expected = grunt.file.read(fixtures + actualFile);

    // cheat a little, first line is the depsWriter.py full path declaration.
    // this breaks tests in each different setup.
    //
    // so, remove first line from both files
    actual = actual.split('\n').splice(1).join('\n');
    expected = expected.split('\n').splice(1).join('\n');

    assert.equal(actual, expected, 'task output should equal: ' + actualFile);

  });
});
<|endoftext|>


<commit_before>describe("WindowTimers", function() {

  var nativeBridge;
  var target;

  beforeEach(function() {
    nativeBridge = new NativeBridgeSpy();
    tabris._reset();
    tabris._init(nativeBridge);
    target = {};
  });

  it("do not overwrite existing window methods", function() {
    var setTimeout = target.setTimeout = function() {};
    var setInterval = target.setInterval = function() {};
    var clearTimeout = target.clearTimeout = function() {};
    var clearInterval = target.clearInterval = function() {};

    tabris._addWindowTimerMethods(target);

    expect(target.setTimeout).toBe(setTimeout);
    expect(target.setInterval).toBe(setInterval);
    expect(target.clearTimeout).toBe(clearTimeout);
    expect(target.clearInterval).toBe(clearInterval);
  });

  describe("created methods", function() {

    beforeEach(function() {
      tabris._addWindowTimerMethods(target);
    });

    describe("setTimeout", function() {

      var delay = 23;
      var taskId;
      var callback;
      var createCall, listenCall, startCall;

      beforeEach(function() {
        callback = jasmine.createSpy("callback");
        taskId = target.setTimeout(callback, delay);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];
        listenCall = nativeBridge.calls({id: createCall.id, op: "listen", event: "Run"})[0];
        startCall = nativeBridge.calls({id: createCall.id, op: "call", method: "start"})[0];
      });

      it("creates native Timer", function() {
        expect(createCall).toBeDefined();
      });

      it("creates native Timer when tabris is being started", function() {
        tabris._ready = false;
        taskId = target.setTimeout(callback, delay);

        tabris._init(nativeBridge);

        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];
        expect(createCall).toBeDefined();
      });

      it("passes arguments to Timer creation", function() {
        expect(createCall.properties.delay).toBe(delay);
        expect(createCall.properties.repeat).toBe(false);
      });

      it("passes 0 delay when argument left out", function() {
        nativeBridge.resetCalls();
        target.setTimeout(callback);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

        expect(createCall.properties.delay).toBe(0);
      });

      it("passes 0 delay when argument is not a number", function() {
        [1 / 0, NaN, "", {}, false].forEach(function(value) {
          nativeBridge.resetCalls();
          target.setTimeout(callback, value);
          createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

          expect(createCall.properties.delay).toBe(0);
        });
      });

      it("passes 0 delay when argument is negative", function() {
        nativeBridge.resetCalls();
        target.setTimeout(callback, -1);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

        expect(createCall.properties.delay).toBe(0);
      });

      it("passes rounded delay", function() {
        nativeBridge.resetCalls();
        target.setTimeout(callback, 3.14);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

        expect(createCall.properties.delay).toBe(3);
      });

      it("listens on Run event of native Timer", function() {
        expect(listenCall).toBeDefined();
      });

      it("starts the native Timer", function() {
        expect(startCall).toBeDefined();
      });

      it("create, listen, start are called in this order", function() {
        var createPosition = nativeBridge.calls().indexOf(createCall);
        var listenPosition = nativeBridge.calls().indexOf(listenCall);
        var startPosition = nativeBridge.calls().indexOf(startCall);
        expect(listenPosition).toBeGreaterThan(createPosition);
        expect(startPosition).toBeGreaterThan(listenPosition);
      });

      it("returns a number", function() {
        expect(typeof taskId).toBe("number");
      });

      it("returns ascending numbers", function() {
        var nextTaskId = target.setTimeout(callback, 23);
        expect(nextTaskId).toBeGreaterThan(taskId);
      });

      describe("when notified", function() {

        beforeEach(function() {
          tabris._notify(createCall.id, "Run", {});
        });

        it("callback is called", function() {
          expect(callback).toHaveBeenCalled();
        });

        it("timer is disposed", function() {
          var destroyCall = nativeBridge.calls({id: createCall.id, op: "destroy"})[0];
          expect(destroyCall).toBeDefined();
        });

      });

      describe("clearTimeout", function() {

        beforeEach(function() {
          target.clearTimeout(taskId);
        });

        it("calls native cancelTask", function() {
          var cancelCall = nativeBridge.calls({id: createCall.id, op: "call", method: "cancel"})[0];
          expect(cancelCall).toBeDefined();
        });

        it("destroys native timer", function() {
          var destroyCall = nativeBridge.calls({id: createCall.id, op: "destroy"})[0];
          expect(destroyCall).toBeDefined();
        });

        it("tolerates unknown taskId", function() {
          expect(function() {
            target.clearTimeout(taskId + 1);
          }).not.toThrow();
        });

      });

      describe("clearInterval", function() {

        beforeEach(function() {
          target.clearInterval(taskId);
        });

        it("calls native cancelTask", function() {
          var cancelCall = nativeBridge.calls({id: createCall.id, op: "call", method: "cancel"})[0];
          expect(cancelCall).toBeDefined();
        });

        it("destroys native timer", function() {
          var destroyCall = nativeBridge.calls({id: createCall.id, op: "destroy"})[0];
          expect(destroyCall).toBeDefined();
        });

        it("tolerates unknown taskId", function() {
          expect(function() {
            target.clearInterval(taskId + 1);
          }).not.toThrow();
        });

      });

    });

    describe("setInterval", function() {

      var delay = 23;
      var taskId;
      var callback;
      var createCall, listenCall, startCall;

      beforeEach(function() {
        callback = jasmine.createSpy("callback");
        taskId = target.setInterval(callback, delay);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];
        listenCall = nativeBridge.calls({id: createCall.id, op: "listen", event: "Run"})[0];
        startCall = nativeBridge.calls({id: createCall.id, op: "call", method: "start"})[0];
      });

      it("creates native Timer", function() {
        expect(createCall).toBeDefined();
      });

      it("passes arguments to Timer creation", function() {
        expect(createCall.properties.delay).toBe(delay);
        expect(createCall.properties.repeat).toBe(true);
      });

      it("passes 0 delay when argument left out", function() {
        nativeBridge.resetCalls();
        target.setInterval(callback);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

        expect(createCall.properties.delay).toBe(0);
      });

      it("passes 0 delay when argument is not a number", function() {
        [1 / 0, NaN, "", {}, false].forEach(function(value) {
          nativeBridge.resetCalls();
          target.setInterval(callback, value);
          createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

          expect(createCall.properties.delay).toBe(0);
        });
      });

      it("passes 0 delay when argument is negative", function() {
        nativeBridge.resetCalls();
        target.setInterval(callback, -1);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

        expect(createCall.properties.delay).toBe(0);
      });

      it("passes rounded delay", function() {
        nativeBridge.resetCalls();
        target.setInterval(callback, 3.14);
        createCall = nativeBridge.calls({op: "create", type: "tabris.Timer"})[0];

        expect(createCall.properties.delay).toBe(3);
      });

      it("listens on Run event of native Timer", function() {
        expect(listenCall).toBeDefined();
      });

      it("starts the native Timer", function() {
        expect(startCall).toBeDefined();
      });

      it("create, listen, start are called in this order", function() {
        var createPosition = nativeBridge.calls().indexOf(createCall);
        var listenPosition = nativeBridge.calls().indexOf(listenCall);
        var startPosition = nativeBridge.calls().indexOf(startCall);
        expect(listenPosition).toBeGreaterThan(createPosition);
        expect(startPosition).toBeGreaterThan(listenPosition);
      });

      it("returns a number", function() {
        expect(typeof taskId).toBe("number");
      });

      it("returns ascending numbers", function() {
        var nextTaskId = target.setInterval(callback, delay);
        expect(nextTaskId).toBeGreaterThan(taskId);
      });

      it("returned numbers don't clash with getTimeout", function() {
        var timeoutTaskId = target.setTimeout(callback, delay);
        expect(timeoutTaskId).toBeGreaterThan(taskId);
      });

      describe("when notified", function() {

        beforeEach(function() {
          tabris._notify(createCall.id, "Run", {});
        });

        it("callback is called", function() {
          expect(callback).toHaveBeenCalled();
        });

        it("callback is called on subsequent Run events", function() {
          tabris._notify(createCall.id, "Run", {});

          expect(callback.calls.count()).toBe(2);
        });

      });

      describe("clearInterval", function() {

        beforeEach(function() {
          target.clearInterval(taskId);
        });

        it("calls native cancelTask", function() {
          var calls = nativeBridge.calls({id: createCall.id, op: "call", method: "cancel"});
          expect(calls.length).toBe(1);
        });

        it("destroys native timer", function() {
          var destroyCall = nativeBridge.calls({id: createCall.id, op: "destroy"})[0];
          expect(destroyCall).toBeDefined();
        });

        it("tolerates unknown taskId", function() {
          expect(function() {
            target.clearInterval(taskId + 1);
          }).not.toThrow();
        });

      });

    });

  });

});
<commit_msg>Refactor WindowTimers.spec.js<commit_after>describe("WindowTimers", function() {

  var nativeBridge;
  var target;

  beforeEach(function() {
    nativeBridge = new NativeBridgeSpy();
    tabris._reset();
    tabris._init(nativeBridge);
    target = {};
  });

  it("do not overwrite existing window methods", function() {
    var setTimeout = target.setTimeout = function() {};
    var setInterval = target.setInterval = function() {};
    var clearTimeout = target.clearTimeout = function() {};
    var clearInterval = target.clearInterval = function() {};

    tabris._addWindowTimerMethods(target);

    expect(target.setTimeout).toBe(setTimeout);
    expect(target.setInterval).toBe(setInterval);
    expect(target.clearTimeout).toBe(clearTimeout);
    expect(target.clearInterval).toBe(clearInterval);
  });

  describe("created methods:", function() {

    var delay = 23;
    var taskId;
    var callback;
    var createCall = function() { return nativeBridge.calls({op: "create", type: "tabris.Timer"})[0]; };
    var listenCall = function() { return nativeBridge.calls({id: createCall().id, op: "listen", event: "Run"})[0]; };
    var startCall = function() { return nativeBridge.calls({id: createCall().id, op: "call", method: "start"})[0]; };

    beforeEach(function() {
      tabris._addWindowTimerMethods(target);
      callback = jasmine.createSpy("callback");
    });

    ["setTimeout", "setInterval"].forEach(function(method) {

      var isInterval = method === "setInterval";

      describe(method, function() {

        describe("when called with delay", function() {

          beforeEach(function() {
            taskId = target[method](callback, delay);
          });

          it("creates native Timer", function() {
            expect(createCall()).toBeDefined();
          });

          it("passes arguments to Timer creation", function() {
            expect(createCall().properties.delay).toBe(delay);
            expect(createCall().properties.repeat).toBe(isInterval);
          });

          it("listens on Run event of native Timer", function() {
            expect(listenCall()).toBeDefined();
          });

          it("starts the native Timer", function() {
            expect(startCall()).toBeDefined();
          });

          it("create, listen, start are called in this order", function() {
            var createPosition = nativeBridge.calls().indexOf(createCall());
            var listenPosition = nativeBridge.calls().indexOf(listenCall());
            var startPosition = nativeBridge.calls().indexOf(startCall());
            expect(listenPosition).toBeGreaterThan(createPosition);
            expect(startPosition).toBeGreaterThan(listenPosition);
          });

          it("returns a number", function() {
            expect(typeof taskId).toBe("number");
          });

          it("returns ascending numbers", function() {
            var nextTaskId = target[method](callback, 23);
            expect(nextTaskId).toBeGreaterThan(taskId);
          });

          it("returned numbers don't clash with other method", function() {
            var otherMethod = isInterval ? "setTimeout" : "setInterval";
            var timeoutTaskId = target[otherMethod](callback, delay);
            expect(timeoutTaskId).toBeGreaterThan(taskId);
          });

          describe("and timer is notified, ", function() {

            beforeEach(function() {
              tabris._notify(createCall().id, "Run", {});
            });

            it("callback is called", function() {
              expect(callback).toHaveBeenCalled();
            });

            if (isInterval) {
              it("timer is not disposed", function() {
                var destroyCall = nativeBridge.calls({id: createCall().id, op: "destroy"})[0];
                expect(destroyCall).not.toBeDefined();
              });
            } else {
              it("timer is disposed", function() {
                var destroyCall = nativeBridge.calls({id: createCall().id, op: "destroy"})[0];
                expect(destroyCall).toBeDefined();
              });
            }

          });

          ["clearTimeout", "clearInterval"].forEach(function(clearMethod) {

            describe("and " + clearMethod + " is called", function() {

              beforeEach(function() {
                target[clearMethod](taskId);
              });

              it("calls native cancelTask", function() {
                var cancelCall = nativeBridge.calls({id: createCall().id, op: "call", method: "cancel"})[0];
                expect(cancelCall).toBeDefined();
              });

              it("destroys native timer", function() {
                var destroyCall = nativeBridge.calls({id: createCall().id, op: "destroy"})[0];
                expect(destroyCall).toBeDefined();
              });

              it("tolerates unknown taskId", function() {
                expect(function() {
                  target.clearInterval(taskId + 1);
                }).not.toThrow();
              });

            });

          });

        });

        it("creates native Timer when tabris is being started", function() {
          tabris._ready = false;
          taskId = target[method](callback, delay);

          tabris._init(nativeBridge);

          expect(createCall()).toBeDefined();
        });

        it("passes 0 delay when argument is left out", function() {
          target[method](callback);

          expect(createCall().properties.delay).toBe(0);
        });

        it("passes 0 delay when argument is not a number", function() {
          [1 / 0, NaN, "", {}, false].forEach(function(value) {
            nativeBridge.resetCalls();
            target[method](callback, value);

            expect(createCall().properties.delay).toBe(0);
          });
        });

        it("passes 0 delay when argument is negative", function() {
          target[method](callback, -1);

          expect(createCall().properties.delay).toBe(0);
        });

        it("passes rounded delay", function() {
          target[method](callback, 3.14);

          expect(createCall().properties.delay).toBe(3);
        });

      });

    });

  });

});
<|endoftext|>


<commit_before>var app = angular.module('myLazyClock', [

    'ui.bootstrap',
    'templates.ui.bootstrap',
    'ui.router',
    'angular-google-gapi',

    'myLazyClock.router',
    'myLazyClock.controller',

]);

app.constant('TRAVELS_MODE',[
    {'name' : 'A pied', 'id' : 'WALKING'},
    {'name' : 'En voiture', 'id' : 'DRIVING'},
    {'name' : 'En vélo', 'id' : 'BICYCLING'}
]);

app.constant('PREPARATION_TIMES',[
    {'name' : '5 minutes', 'time' : '300'},
    {'name' : '15 minutes', 'time' : '900'},
    {'name' : '20 minutes', 'time' : '1200'}
]);

app.config(function ($provide) {
  $provide.decorator('$uiViewScroll', function ($delegate) {
    return function (uiViewElement) {
      window.scrollTo(0, (top - 30));
      // Or some other custom behaviour...
    };
  });
});

app.run(['GAuth', 'GApi', '$state',
    function(GAuth, GApi, $state) {

        var CLIENT;
        var BASE;
        if(window.location.hostname == 'localhost') {
            if(window.location.port == '8080') {
                CLIENT = '1072024627812-kgv1uou2btdphtvb2l2bbh14n6u2n2mg.apps.googleusercontent.com';
                BASE = '//localhost:8080/_ah/api';
            } else {
                CLIENT = '1072024627812-69lrpihiunbo6rrpqpnkho7djdl5fu74.apps.googleusercontent.com';
                BASE = '//localhost:8080/_ah/api';
            }
        } else {
            CLIENT = '1072024627812-oh4jdt3mo6rihojkt480tqfsja2706b4.apps.googleusercontent.com';
            BASE = 'https://mylazyclock.appspot.com/_ah/api';
        }

        GApi.load('myLazyClock','v1',BASE);
        GApi.load('calendar','v3');
        GAuth.setClient(CLIENT);
        GAuth.setScopes(['https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/calendar.readonly']);
        GAuth.checkAuth().then(
            function () {
                if($state.includes('login'))
                    $state.go('webapp.home');
            },
            function() {
                $state.go('login');
            }
        );
    }
]);<commit_msg>add Transit travel-mode in UI<commit_after>var app = angular.module('myLazyClock', [

    'ui.bootstrap',
    'templates.ui.bootstrap',
    'ui.router',
    'angular-google-gapi',

    'myLazyClock.router',
    'myLazyClock.controller',

]);

app.constant('TRAVELS_MODE',[
    {'name' : 'A pied', 'id' : 'WALKING'},
    {'name' : 'En voiture', 'id' : 'DRIVING'},
    {'name' : 'En vélo', 'id' : 'BICYCLING'},
    {'name' : 'En Transport', 'id' : 'TRANSIT'}
]);

app.constant('PREPARATION_TIMES',[
    {'name' : '5 minutes', 'time' : '300'},
    {'name' : '15 minutes', 'time' : '900'},
    {'name' : '20 minutes', 'time' : '1200'}
]);

app.config(function ($provide) {
  $provide.decorator('$uiViewScroll', function ($delegate) {
    return function (uiViewElement) {
      window.scrollTo(0, (top - 30));
      // Or some other custom behaviour...
    };
  });
});

app.run(['GAuth', 'GApi', '$state',
    function(GAuth, GApi, $state) {

        var CLIENT;
        var BASE;
        if(window.location.hostname == 'localhost') {
            if(window.location.port == '8080') {
                CLIENT = '1072024627812-kgv1uou2btdphtvb2l2bbh14n6u2n2mg.apps.googleusercontent.com';
                BASE = '//localhost:8080/_ah/api';
            } else {
                CLIENT = '1072024627812-69lrpihiunbo6rrpqpnkho7djdl5fu74.apps.googleusercontent.com';
                BASE = '//localhost:8080/_ah/api';
            }
        } else {
            CLIENT = '1072024627812-oh4jdt3mo6rihojkt480tqfsja2706b4.apps.googleusercontent.com';
            BASE = 'https://mylazyclock.appspot.com/_ah/api';
        }

        GApi.load('myLazyClock','v1',BASE);
        GApi.load('calendar','v3');
        GAuth.setClient(CLIENT);
        GAuth.setScopes(['https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/calendar.readonly']);
        GAuth.checkAuth().then(
            function () {
                if($state.includes('login'))
                    $state.go('webapp.home');
            },
            function() {
                $state.go('login');
            }
        );
    }
]);<|endoftext|>