<commit_before>const path = require('path');
const ls = require('./ls.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const plugins = [];
const entry = {};

// The dev mode will be used for builds on local machine outside docker
const nodeEnv = process.env['NODE_ENV'] || 'development';
const dev = nodeEnv == 'development'

for (const filename of ls(path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js/apps/*.html.ejs'))) {
  const name = filename.file.substr(0, filename.file.length - '.html.ejs'.length);
  entry[name] = '/app/geoportailv3_geoportal/static-ngeo/js/apps/' + name.charAt(0).toUpperCase() + name.slice(1) + 'Controller.js';
  plugins.push(
    new HtmlWebpackPlugin({
      template: filename.full,
      inject: false,
      chunksSortMode: 'manual',
      filename: name + '.html',
      chunks: [name],
      vars: {
        entry_point: '${VISIBLE_ENTRY_POINT}',
        version: '2.5.0.77',
        cache_version: '${CACHE_VERSION}',
       },
    })
  );
}

const babelPresets = [[require.resolve('@babel/preset-env'), {
  targets: {
    browsers: ['> 0.5% in CH', '> 0.5% in FR', 'Firefox ESR', 'ie 11'],
  },
  modules: false,
  loose: true,
}]]

// Transform code to ES2015 and annotate injectable functions with an $inject array.
const projectRule = {
  test: /geoportailv3_geoportal\/static-ngeo\/js\/.*\.js$/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: babelPresets,
      babelrc: false,
      comments: false,
      plugins: [
        require.resolve('@babel/plugin-syntax-object-rest-spread'),
        require.resolve('@babel/plugin-transform-spread'),
        require.resolve('@camptocamp/babel-plugin-angularjs-annotate'),
      ],
    }
  },
};

const rules = [
  projectRule,
];

const noDevServer = process.env['NO_DEV_SERVER'] == 'TRUE';
const devServer = dev && !noDevServer;

console.log("Use dev mode: " + dev)
console.log("Use dev server mode: " + devServer)

module.exports = {
  output: {
    path: '/etc/static-ngeo/',
    publicPath: devServer ? '${VISIBLE_ENTRY_POINT}dev/' : '.__ENTRY_POINT__static-ngeo/'
  },
  devServer: {
    publicPath: '${VISIBLE_WEB_PROTOCOL}://${VISIBLE_WEB_HOST}${VISIBLE_ENTRY_POINT}dev/',
    port: 8080,
    host: 'webpack_dev_server',
    hot: true,
  },
  entry: entry,
  module: {
    rules
  },
  plugins: plugins,
  resolve: {
    modules: ['/usr/lib/node_modules'],
    alias: {
      geoportailv3: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js'),
    },
  },
};
<commit_msg>Update geoportal/webpack.apps.js<commit_after>const path = require('path');
const ls = require('ngeo/buildtools/ls.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const plugins = [];
const entry = {};

// The dev mode will be used for builds on local machine outside docker
const nodeEnv = process.env['NODE_ENV'] || 'development';
const dev = nodeEnv == 'development'

for (const filename of ls(path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js/apps/*.html.ejs'))) {
  const name = filename.file.substr(0, filename.file.length - '.html.ejs'.length);
  entry[name] = 'geoportailv3/apps/' + name.charAt(0).toUpperCase() + name.slice(1) + 'Controller.js';
  plugins.push(
    new HtmlWebpackPlugin({
      template: filename.full,
      inject: false,
      chunksSortMode: 'manual',
      filename: name + '.html',
      chunks: [name],
      vars: {
        entry_point: '${VISIBLE_ENTRY_POINT}',
        version: '2.5.0.88',
        cache_version: '${CACHE_VERSION}',
       },
    })
  );
}

const babelPresets = [[require.resolve('@babel/preset-env'), {
  targets: {
    browsers: ['> 0.5% in CH', '> 0.5% in FR', 'Firefox ESR', 'ie 11'],
  },
  modules: false,
  loose: true,
}]]

// Transform code to ES2015 and annotate injectable functions with an $inject array.
const projectRule = {
  test: /geoportailv3_geoportal\/static-ngeo\/js\/.*\.js$/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: babelPresets,
      babelrc: false,
      comments: false,
      plugins: [
        require.resolve('@babel/plugin-syntax-object-rest-spread'),
        require.resolve('@babel/plugin-transform-spread'),
        require.resolve('@camptocamp/babel-plugin-angularjs-annotate'),
      ],
    }
  },
};

const rules = [
  projectRule,
];

const noDevServer = process.env['NO_DEV_SERVER'] == 'TRUE';
const devServer = dev && !noDevServer;

console.log("Use dev mode: " + dev)
console.log("Use dev server mode: " + devServer)

module.exports = {
  output: {
    path: '/etc/static-ngeo/',
    publicPath: devServer ? '${VISIBLE_ENTRY_POINT}dev/' : '.__ENTRY_POINT__static-ngeo/'
  },
  devServer: {
    publicPath: '${VISIBLE_WEB_PROTOCOL}://${VISIBLE_WEB_HOST}${VISIBLE_ENTRY_POINT}dev/',
    port: 8080,
    host: 'webpack_dev_server',
    hot: true,
  },
  entry: entry,
  module: {
    rules
  },
  plugins: plugins,
  resolve: {
    modules: ['/usr/lib/node_modules'],
    alias: {
      geoportailv3: path.resolve(__dirname, 'geoportailv3_geoportal/static-ngeo/js'),
    },
  },
};
<|endoftext|>


<commit_before>const AwsCredentials = require('../lib/aws-credentials');
const should = require('should');
const Path = require('path');
const FS = require('fs');
const ini = require('ini');

describe('AwsCredentials#saveAsIniFile', function() {
  const awsFolder = Path.resolve(__dirname, '.aws');
  const awsCredentials = Path.resolve(awsFolder, 'credentials');

  beforeEach(function() {
    if (FS.existsSync(awsCredentials)) {
      FS.unlinkSync(awsCredentials);
    }

    if (FS.existsSync(awsFolder)) {
      FS.rmdirSync(awsFolder);
    }
  });

  it('returns an error when credentials are null', function(done) {
    const aws = new AwsCredentials();

    aws.saveAsIniFile(null, 'profile', (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('returns an error when profile is null', function(done) {
    const aws = new AwsCredentials();

    aws.saveAsIniFile({}, null, (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('returns an error when $HOME path is unresolved', function(done) {
    const aws = new AwsCredentials();

    delete process.env.HOME;
    delete process.env.USERPROFILE;
    delete process.env.HOMEPATH;
    delete process.env.HOMEDRIVE;

    aws.saveAsIniFile({}, 'profile', (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('returns an error when $HOME path is empty', function(done) {
    const aws = new AwsCredentials();

    process.env.HOME = '';

    aws.saveAsIniFile({}, 'profile', (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('creates a $HOME/.aws folder when none exists', function(done) {
    const aws = new AwsCredentials();

    process.env.HOME = __dirname;

    aws.saveAsIniFile({}, 'profile', (error) => {
      should(FS.existsSync(awsFolder)).be.true();
      should(error).be.null();
      done();
    });
  });

  it('creates a $HOME/.aws folder with 0700 permissions', function(done) {
    const aws = new AwsCredentials();

    process.env.HOME = __dirname;

    aws.saveAsIniFile({}, 'profile', (error) => {
      should(FS.statSync(awsFolder).mode & 0x0700).eql(256); // eslint-disable-line no-bitwise
      should(error).be.null();
      done();
    });
  });

  it('saves the access key in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      AccessKeyId: 'AccessKeyId'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_access_key_id).eql(credentials.AccessKeyId);
      done();
    });
  });

  it('saves the secret key in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      SecretAccessKey: 'SecretAccessKey'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_secret_access_key).eql(credentials.SecretAccessKey);
      done();
    });
  });

  it('saves the session token in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      SessionToken: 'SessionToken'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_session_token).eql(credentials.SessionToken);
      done();
    });
  });

  it('saves the session token as a security token in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      SessionToken: 'SessionToken'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_security_token).eql(credentials.SessionToken);
      done();
    });
  });

  it('keeps existing profiles', function(done) {
    const aws = new AwsCredentials();
    const credentials1 = {
      AccessKeyId: 'AccessKeyId1',
      SecretAccessKey: 'SecretAccessKey1',
      SessionToken: 'SessionToken1'
    };
    const credentials2 = {
      AccessKeyId: 'AccessKeyId2',
      SecretAccessKey: 'SecretAccessKey2',
      SessionToken: 'SessionToken2'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials1, 'profile1', () => {
      aws.saveAsIniFile(credentials2, 'profile2', () => {
        const data = FS.readFileSync(awsCredentials, 'utf-8');
        const config = ini.parse(data);

        should(config.profile1).eql({
          aws_access_key_id: credentials1.AccessKeyId,
          aws_secret_access_key: credentials1.SecretAccessKey,
          aws_session_token: credentials1.SessionToken,
          aws_security_token: credentials1.SessionToken
        });
        should(config.profile2).eql({
          aws_access_key_id: credentials2.AccessKeyId,
          aws_secret_access_key: credentials2.SecretAccessKey,
          aws_session_token: credentials2.SessionToken,
          aws_security_token: credentials2.SessionToken
        });

        done();
      });
    });
  });
});

describe('AwsCredentials#resolveHomePath', function() {
  beforeEach(function() {
    delete process.env.HOME;
    delete process.env.USERPROFILE;
    delete process.env.HOMEPATH;
    delete process.env.HOMEDRIVE;
  });

  it('returns null if $HOME, $USERPROFILE, and $HOMEPATH are undefined', function() {
    should(AwsCredentials.resolveHomePath()).be.null();
  });

  it('uses $HOME if defined', function() {
    process.env.HOME = 'HOME';

    should(AwsCredentials.resolveHomePath()).eql('HOME');
  });

  it('uses $USERPROFILE if $HOME is undefined', function() {
    process.env.USERPROFILE = 'USERPROFILE';

    should(AwsCredentials.resolveHomePath()).eql('USERPROFILE');
  });

  it('uses $HOMEPATH if $HOME and $USERPROFILE are undefined', function() {
    process.env.HOMEPATH = 'HOMEPATH';

    should(AwsCredentials.resolveHomePath()).eql('C:/HOMEPATH');
  });

  it('uses $HOMEDRIVE with $HOMEPATH if defined', function() {
    process.env.HOMEPATH = 'HOMEPATH';
    process.env.HOMEDRIVE = 'D:/';

    should(AwsCredentials.resolveHomePath()).eql('D:/HOMEPATH');
  });
});
<commit_msg>Fixed a missed path change.<commit_after>const AwsCredentials = require('../api/aws-credentials');
const should = require('should');
const Path = require('path');
const FS = require('fs');
const ini = require('ini');

describe('AwsCredentials#saveAsIniFile', function() {
  const awsFolder = Path.resolve(__dirname, '.aws');
  const awsCredentials = Path.resolve(awsFolder, 'credentials');

  beforeEach(function() {
    if (FS.existsSync(awsCredentials)) {
      FS.unlinkSync(awsCredentials);
    }

    if (FS.existsSync(awsFolder)) {
      FS.rmdirSync(awsFolder);
    }
  });

  it('returns an error when credentials are null', function(done) {
    const aws = new AwsCredentials();

    aws.saveAsIniFile(null, 'profile', (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('returns an error when profile is null', function(done) {
    const aws = new AwsCredentials();

    aws.saveAsIniFile({}, null, (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('returns an error when $HOME path is unresolved', function(done) {
    const aws = new AwsCredentials();

    delete process.env.HOME;
    delete process.env.USERPROFILE;
    delete process.env.HOMEPATH;
    delete process.env.HOMEDRIVE;

    aws.saveAsIniFile({}, 'profile', (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('returns an error when $HOME path is empty', function(done) {
    const aws = new AwsCredentials();

    process.env.HOME = '';

    aws.saveAsIniFile({}, 'profile', (error) => {
      error.toString().should.not.eql('');
      done();
    });
  });

  it('creates a $HOME/.aws folder when none exists', function(done) {
    const aws = new AwsCredentials();

    process.env.HOME = __dirname;

    aws.saveAsIniFile({}, 'profile', (error) => {
      should(FS.existsSync(awsFolder)).be.true();
      should(error).be.null();
      done();
    });
  });

  it('creates a $HOME/.aws folder with 0700 permissions', function(done) {
    const aws = new AwsCredentials();

    process.env.HOME = __dirname;

    aws.saveAsIniFile({}, 'profile', (error) => {
      should(FS.statSync(awsFolder).mode & 0x0700).eql(256); // eslint-disable-line no-bitwise
      should(error).be.null();
      done();
    });
  });

  it('saves the access key in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      AccessKeyId: 'AccessKeyId'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_access_key_id).eql(credentials.AccessKeyId);
      done();
    });
  });

  it('saves the secret key in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      SecretAccessKey: 'SecretAccessKey'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_secret_access_key).eql(credentials.SecretAccessKey);
      done();
    });
  });

  it('saves the session token in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      SessionToken: 'SessionToken'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_session_token).eql(credentials.SessionToken);
      done();
    });
  });

  it('saves the session token as a security token in the credentials file', function(done) {
    const aws = new AwsCredentials();
    const credentials = {
      SessionToken: 'SessionToken'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials, 'profile', (error) => {
      const data = FS.readFileSync(awsCredentials, 'utf-8');
      const config = ini.parse(data);

      should(error).be.null();
      should(config.profile.aws_security_token).eql(credentials.SessionToken);
      done();
    });
  });

  it('keeps existing profiles', function(done) {
    const aws = new AwsCredentials();
    const credentials1 = {
      AccessKeyId: 'AccessKeyId1',
      SecretAccessKey: 'SecretAccessKey1',
      SessionToken: 'SessionToken1'
    };
    const credentials2 = {
      AccessKeyId: 'AccessKeyId2',
      SecretAccessKey: 'SecretAccessKey2',
      SessionToken: 'SessionToken2'
    };

    process.env.HOME = __dirname;

    aws.saveAsIniFile(credentials1, 'profile1', () => {
      aws.saveAsIniFile(credentials2, 'profile2', () => {
        const data = FS.readFileSync(awsCredentials, 'utf-8');
        const config = ini.parse(data);

        should(config.profile1).eql({
          aws_access_key_id: credentials1.AccessKeyId,
          aws_secret_access_key: credentials1.SecretAccessKey,
          aws_session_token: credentials1.SessionToken,
          aws_security_token: credentials1.SessionToken
        });
        should(config.profile2).eql({
          aws_access_key_id: credentials2.AccessKeyId,
          aws_secret_access_key: credentials2.SecretAccessKey,
          aws_session_token: credentials2.SessionToken,
          aws_security_token: credentials2.SessionToken
        });

        done();
      });
    });
  });
});

describe('AwsCredentials#resolveHomePath', function() {
  beforeEach(function() {
    delete process.env.HOME;
    delete process.env.USERPROFILE;
    delete process.env.HOMEPATH;
    delete process.env.HOMEDRIVE;
  });

  it('returns null if $HOME, $USERPROFILE, and $HOMEPATH are undefined', function() {
    should(AwsCredentials.resolveHomePath()).be.null();
  });

  it('uses $HOME if defined', function() {
    process.env.HOME = 'HOME';

    should(AwsCredentials.resolveHomePath()).eql('HOME');
  });

  it('uses $USERPROFILE if $HOME is undefined', function() {
    process.env.USERPROFILE = 'USERPROFILE';

    should(AwsCredentials.resolveHomePath()).eql('USERPROFILE');
  });

  it('uses $HOMEPATH if $HOME and $USERPROFILE are undefined', function() {
    process.env.HOMEPATH = 'HOMEPATH';

    should(AwsCredentials.resolveHomePath()).eql('C:/HOMEPATH');
  });

  it('uses $HOMEDRIVE with $HOMEPATH if defined', function() {
    process.env.HOMEPATH = 'HOMEPATH';
    process.env.HOMEDRIVE = 'D:/';

    should(AwsCredentials.resolveHomePath()).eql('D:/HOMEPATH');
  });
});
<|endoftext|>


<commit_before>require('dotenv').config();
const User = require('../database/models').User;
const jwt = require('jsonwebtoken');
const _ = require('lodash');
const Validator = require('validatorjs');
const { handleError, handleSuccess } = require('../helpers/helpers');

module.exports = {
  signup(req, res) {
    const obj = req.body;
    const validator = new Validator(obj, User.signupRules());
    if (validator.passes() && obj.confirm_password) {
      if (obj.confirm_password !== obj.password) {
        return handleError('password not matched', res);
      }
      User.findOne({
        where: {
          $or: [{ email: obj.email }, { mobile: obj.mobile }, { username: obj.username }]
        }
      })
          .then((existingUser) => {
            if (existingUser) {
              let message = '';
              if (existingUser.email === obj.email) message = 'A user with this email already exists';
              if (existingUser.mobile === obj.mobile) message = 'This Mobile Number has been used';
              if (existingUser.username === obj.username) message = 'This Username has been used';
              return Promise.reject(message);
            }
            // if user does not exist and he/she registering for the first time
            if (!req.body.mobile) {
              obj.mobile = '';
            }
            return User.create(obj, { fields: ['email', 'password', 'username', 'mobile', 'fullname'] });
          })
          .then(savedUser => handleSuccess(201, savedUser, res))
          .catch(err => res.status(400).send(err));
    } else {
      return res.status(400).send({ message: 'There are problems with your input' });
    }
  },
  signin(req, res) {
    const body = _.pick(req.body, ['username', 'password']);
    const validator = new Validator(body, User.loginRules());
    if (!validator.passes()) {
      return res.status(400).send({ message: 'There are problems with your input' });
    }
    User.findOne({
      where: {
        username: body.username
      }
    })
        .then((user) => {
          if (!user) {
            return res.status(404).send({ message: 'User not found' });
          }
          if (!user.comparePassword(body.password)) {
            return res.status(404).send({ message: 'Incorrect password' });
          }
          const data = _.pick(user, ['id', 'username', 'email', 'mobile']);
          const token = jwt.sign(data, process.env.JWT_SECRET, { expiresIn: 86400 }); // should expire in 24 hours
          return res.status(200).send({ token, message: 'Sign in successful' });
        })
        .catch(err => res.status(400).send(err));
  }
};

<commit_msg>remove unncessary response body<commit_after>require('dotenv').config();
const User = require('../database/models').User;
const jwt = require('jsonwebtoken');
const _ = require('lodash');
const Validator = require('validatorjs');
const { handleError, handleSuccess } = require('../helpers/helpers');

module.exports = {
  signup(req, res) {
    const obj = req.body;
    const validator = new Validator(obj, User.signupRules());
    if (validator.passes() && obj.confirm_password) {
      if (obj.confirm_password !== obj.password) {
        return handleError('password not matched', res);
      }
      User.findOne({
        where: {
          $or: [{ email: obj.email }, { mobile: obj.mobile }, { username: obj.username }]
        }
      })
          .then((existingUser) => {
            if (existingUser) {
              let message = '';
              if (existingUser.email === obj.email) message = 'A user with this email already exists';
              if (existingUser.mobile === obj.mobile) message = 'This Mobile Number has been used';
              if (existingUser.username === obj.username) message = 'This Username has been used';
              return Promise.reject(message);
            }
            // if user does not exist and he/she registering for the first time
            if (!req.body.mobile) {
              obj.mobile = '';
            }
            return User.create(obj, { fields: ['email', 'password', 'username', 'mobile', 'fullname'] });
          })
          .then(savedUser => handleSuccess(201, savedUser, res))
          .catch(err => res.status(400).send(err));
    } else {
      return handleError('There are problems with your input', res);
    }
  },
  signin(req, res) {
    const body = _.pick(req.body, ['username', 'password']);
    const validator = new Validator(body, User.loginRules());
    if (!validator.passes()) {
      return res.status(400).send({ message: 'There are problems with your input' });
    }
    User.findOne({
      where: {
        username: body.username
      }
    })
        .then((user) => {
          if (!user) {
            return res.status(404).send({ message: 'User not found' });
          }
          if (!user.comparePassword(body.password)) {
            return res.status(404).send({ message: 'Incorrect password' });
          }
          const data = _.pick(user, ['id', 'username', 'email', 'mobile']);
          const token = jwt.sign(data, process.env.JWT_SECRET, { expiresIn: 86400 }); // should expire in 24 hours
          return res.status(200).send({ token, message: 'Sign in successful' });
        })
        .catch(err => res.status(400).send(err));
  }
};

<|endoftext|>


<commit_before><commit_msg>change core.constats.js<commit_after><|endoftext|>


<commit_before>const Promise = require('bluebird')
const ldap = require('ldapjs')

async function getBoundClient () {
  const url = process.env.LDAP_URL || 'ldaps://ldap.kth.se'
  console.log('Should get ldap client connected to', url)
  const ldapClient = Promise.promisifyAll(ldap.createClient({
    url: url,
    connectTimeout: 1000
  }))
  await ldapClient.bindAsync(process.env.LDAP_USERNAME, process.env.LDAP_PASSWORD)
  return ldapClient
}

async function lookupUser (ldapClient, kthid) {
  const attributes = ['givenName', 'sn', 'norEduPersonNIN']
  const ldapResults = await ldapClient.searchAsync('ou=UG,dc=referens,dc=sys,dc=kth,dc=se', {
    scope: 'sub',
    filter: `(ugKthId=${kthid})`,
    timeLimit: 10,
    paging: true,
    attributes,
    paged: {
      pageSize: 1000,
      pagePause: false
    }
  })
  const ugUser = await new Promise((resolve, reject) => {
    const user = []
    ldapResults.on('searchEntry', ({object}) => user.push(object))
    ldapResults.on('end', () => resolve(user))
    ldapResults.on('error', reject)
  })
  if (ugUser.length > 0) {
    return ugUser[0]
  } else {
    return {}
  }
}

module.exports = {
  getBoundClient,
  lookupUser
}
<commit_msg>Provide ldap timeout.<commit_after>const Promise = require('bluebird')
const ldap = require('ldapjs')

async function getBoundClient () {
  const url = process.env.LDAP_URL || 'ldaps://ldap.kth.se'
  console.log('Should get ldap client connected to', url)
  const ldapClient = Promise.promisifyAll(ldap.createClient({
    url: url,
    timeout: 1000,
    connectTimeout: 1000
  }))
  await ldapClient.bindAsync(process.env.LDAP_USERNAME, process.env.LDAP_PASSWORD)
  return ldapClient
}

async function lookupUser (ldapClient, kthid) {
  const attributes = ['givenName', 'sn', 'norEduPersonNIN']
  const ldapResults = await ldapClient.searchAsync('ou=UG,dc=referens,dc=sys,dc=kth,dc=se', {
    scope: 'sub',
    filter: `(ugKthId=${kthid})`,
    timeLimit: 10,
    paging: true,
    attributes,
    paged: {
      pageSize: 1000,
      pagePause: false
    }
  })
  const ugUser = await new Promise((resolve, reject) => {
    const user = []
    ldapResults.on('searchEntry', ({object}) => user.push(object))
    ldapResults.on('end', () => resolve(user))
    ldapResults.on('error', reject)
  })
  if (ugUser.length > 0) {
    return ugUser[0]
  } else {
    return {}
  }
}

module.exports = {
  getBoundClient,
  lookupUser
}
<|endoftext|>


<commit_before>var db = require('./config');
var util = require('../core/utilities');

// insert(string, object)
exports.insert = function(table, data) {
  return new Promise(function(resolve, reject) {
    var query = 'INSERT INTO ?? SET ?';
    var params = [table, data];
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//selectAll(string tableName)
exports.selectAll = function(table) {
  return new Promise(function(resolve, reject) {
    var query = 'SELECT * FROM ??';
    db.connection.query(query, table, function(err, fields) {
      if (err) {
        reject(err);
      } else {
        resolve(fields);
      }
    });
  });
};

//filters is an array of key value pairs
//filters follows this structure:
// -- [key1, value1, key2, value2 ...etc]
// where(string tableName, [string key1, string value1])
exports.where = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var query = 'SELECT * FROM ?? WHERE ?? = ?';
    var params = ([table]).concat(filters);
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//update(string tableName, [string key1, string value1, string key2, string value2]);
exports.update = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var params = ([table]).concat(filters);
    var query = 'UPDATE ?? SET ?? = ? WHERE ?? = ?';
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//deleteRow(string tableName, [string key, string value]);
exports.deleteRow = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var params = ([table]).concat(filters);
    var query = 'DELETE FROM ?? WHERE ?? = ?';
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//retrieveCount(string tableName, [string key, string value])
exports.retrieveCount = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var params = ([table]).concat(filters);
    var query = 'SELECT COUNT(*) FROM ?? WHERE ?? = ?';
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection[0]["COUNT(*)"]);
      }
    });
  });
};

//exports.retrieveMarks({x: float, y: float, z: float, userToken: string})
exports.retrieveMarks = function(userData) {
  return new Promise(function(resolve, reject) {
    var query = ([
        'SELECT',
        'marks.*,',
        'messages.*,',
        'COUNT(distinct comments.id),',
        'COUNT(distinct votes.id)',
        'FROM messages',
        'LEFT JOIN marks ON marks.messageId = messages.id',
        'LEFT JOIN votes ON votes.messageId = messages.id',
        'LEFT JOIN comments ON comments.messageId = messages.id',
        'GROUP BY messages.id',
        'ORDER BY marks.timestamp DESC'
    ]).join(' ');

    var params = [
      +userData.x - .01,
      +userData.x + .01,
      +userData.y - .01,
        +userData.y + .01
    ];

    db.connection.query(query, params, function(err, marks) {
      if (err) {
        reject(err);
      } else {
        resolve(util.createMessageResponseObjects(marks, userData));
      }
    });
  });
};

exports.retrieveComments = function(userData) {
  return new Promise(function(resolve, reject) {
    var query = ([
      'SELECT',
      'marks.*,',
      'comments.commentString,',
      'COUNT(votes.id)',
      'FROM comments',
      'LEFT JOIN marks ON marks.commentId = comments.id',
      'LEFT JOIN votes ON votes.commentId = comments.id',
      'WHERE comments.messageId = ?',
      'GROUP BY comments.id'
    ]).join(' ');

    var params = [userData.messageId];

    db.connection.query(query, params, function(err, marks) {
      if (err) {
        reject(err);
      } else {
        resolve(util.createCommentResponseObjects(marks, userData));
      }
    });
  });
};
<commit_msg>Add auxiliary where and delete adapters<commit_after>var db = require('./config');
var util = require('../core/utilities');

// insert(string, object)
exports.insert = function(table, data) {
  return new Promise(function(resolve, reject) {
    var query = 'INSERT INTO ?? SET ?';
    var params = [table, data];
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//selectAll(string tableName)
exports.selectAll = function(table) {
  return new Promise(function(resolve, reject) {
    var query = 'SELECT * FROM ??';
    db.connection.query(query, table, function(err, fields) {
      if (err) {
        reject(err);
      } else {
        resolve(fields);
      }
    });
  });
};

//filters is an array of key value pairs
//filters follows this structure:
// -- [key1, value1, key2, value2 ...etc]
// where(string tableName, [string key1, string value1])
exports.where = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var query = 'SELECT * FROM ?? WHERE ?? = ?';
    var params = ([table]).concat(filters);
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//filters is an array of key value pairs
//filters follows this structure:
// -- [key1, value1, key2, value2 ...etc]
// where(string tableName, [string key1, string value1])
exports.whereParams = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var query = 'SELECT * FROM ?? WHERE ?? = ?';
    var params = ([table]).concat(filters);

    for (var i = 1; i < filters.length / 2; i++) {
      query += ' AND ?? = ?';
    }

    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//update(string tableName, [string key1, string value1, string key2, string value2]);
exports.update = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var params = ([table]).concat(filters);
    var query = 'UPDATE ?? SET ?? = ? WHERE ?? = ?';
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//deleteRow(string tableName, [string key, string value]);
exports.deleteRow = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var params = ([table]).concat(filters);
    var query = 'DELETE FROM ?? WHERE ?? = ?';
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//deleteRow(string tableName, [string key, string value]);
exports.deleteRowWhere = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var params = ([table]).concat(filters);
    var query = 'DELETE FROM ?? WHERE ?? = ?';

    for (var i = 1; i < filters.length / 2; i++) {
      query += ' AND ?? = ?';
    }

    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection);
      }
    });
  });
};

//retrieveCount(string tableName, [string key, string value])
exports.retrieveCount = function(table, filters) {
  return new Promise(function(resolve, reject) {
    var params = ([table]).concat(filters);
    var query = 'SELECT COUNT(*) FROM ?? WHERE ?? = ?';
    db.connection.query(query, params, function(err, connection) {
      if (err) {
        reject(err);
      } else {
        resolve(connection[0]["COUNT(*)"]);
      }
    });
  });
};

//exports.retrieveMarks({x: float, y: float, z: float, userToken: string})
exports.retrieveMarks = function(userData) {
  return new Promise(function(resolve, reject) {
    var query = ([
        'SELECT',
        'marks.*,',
        'messages.*,',
        'COUNT(distinct comments.id),',
        'COUNT(distinct votes.id)',
        'FROM messages',
        'LEFT JOIN marks ON marks.messageId = messages.id',
        'LEFT JOIN votes ON votes.messageId = messages.id',
        'LEFT JOIN comments ON comments.messageId = messages.id',
        'GROUP BY messages.id',
        'ORDER BY marks.timestamp DESC'
    ]).join(' ');

    var params = [
      +userData.x - .01,
      +userData.x + .01,
      +userData.y - .01,
        +userData.y + .01
    ];

    db.connection.query(query, params, function(err, marks) {
      if (err) {
        reject(err);
      } else {
        resolve(util.createMessageResponseObjects(marks, userData));
      }
    });
  });
};

exports.retrieveComments = function(userData) {
  return new Promise(function(resolve, reject) {
    var query = ([
      'SELECT',
      'marks.*,',
      'comments.commentString,',
      'COUNT(votes.id)',
      'FROM comments',
      'LEFT JOIN marks ON marks.commentId = comments.id',
      'LEFT JOIN votes ON votes.commentId = comments.id',
      'WHERE comments.messageId = ?',
      'GROUP BY comments.id'
    ]).join(' ');

    var params = [userData.messageId];

    db.connection.query(query, params, function(err, marks) {
      if (err) {
        reject(err);
      } else {
        resolve(util.createCommentResponseObjects(marks, userData));
      }
    });
  });
};
<|endoftext|>


<commit_before>'use strict';

const Boom = require('boom');
const Joi = require('joi');
const Logger = require('@modulus/logger')('server/handlers/project');

const Project = require('../models/project');

exports.create = {
  validate: {
    payload: {
      name: Joi.string().required(),
      maintainers: Joi.array(),
      description: Joi.string(),
      hasLinter: Joi.boolean(),
      hasReadme: Joi.boolean()
    }
  },
  handler: (request, reply) => {
    Project.find({ name: request.payload.name }, (err, foundProject) => {
      if (err) {
        Logger.error(`projects.find ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (foundProject.length > 0) {
        Logger.error(
          `projects.find Project ${request.payload.name} already exists`
        );
        return reply(Boom.badRequest('A project by that name already exists.'));
      }

      const toCreate = {
        name: request.payload.name,
        maintainers: request.payload.maintainers || [],
        description: request.payload.description || '',
        hasLinter: request.payload.hasLinter || false,
        hasReadme: request.payload.hasReadme || false
      };

      new Project(toCreate).save((err, newProject) => {
        if (err) {
          Logger.error(`projects.create ${err.message}`);
          return reply(Boom.badRequest(err));
        }

        reply(newProject);
      });
    });
  }
};

exports.delete = {
  validate: {
    params: {
      name: Joi.string().required()
    }
  },
  handler: (request, reply) => {
    Project.remove({ name: request.params.name }, (err, foundProject) => {
      if (err) {
        Logger.error(`projects.destroy ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (foundProject.length === 0) {
        Logger.error('projects.destroy Project not found');
        return reply(Boom.notFound('Project not found.'));
      }

      reply();
    });
  }
};

exports.getOne = {
  validate: {
    params: {
      name: Joi.string().required()
    }
  },
  handler: (request, reply) => {
    Project.findOne({
      name: request.params.name
    })
    .populate('versions')
    .exec((err, foundProject) => {
      if (err) {
        Logger.error(`projects.findOne ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (!foundProject) {
        Logger.error(
          `projects.findOne Project ${request.payload.name} not found`
        );
        return reply(Boom.badRequest('Project not found.'));
      }

      reply(foundProject);
    });
  }
};

exports.getAll = {
  handler: (request, reply) => {
    Project.find({}).populate('versions').exec((err, foundProject) => {
      if (err) {
        Logger.error(`projects.find ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      reply(foundProject);
    });
  }
};

exports.update = {
  validate: {
    params: {
      name: Joi.string().required()
    },
    payload: {
      name: Joi.string(),
      maintainers: Joi.array(),
      description: Joi.string(),
      hasLinter: Joi.boolean(),
      hasReadme: Joi.boolean()
    }
  },
  handler: (request, reply) => {
    Project.update({
      name: request.params.name
    }, request.payload, (err, updatedProject) => {
      if (err) {
        Logger.error(`projects.findOne ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (updatedProject.length < 1) {
        Logger.error(`projects.find Project ${request.payload.name} not found`);
        return reply(Boom.badRequest('Project not found.'));
      }

      reply(updatedProject);
    });
  }
};
<commit_msg>Add license and node + npm engines to create and update routes<commit_after>'use strict';

const Boom = require('boom');
const Joi = require('joi');
const Logger = require('@modulus/logger')('server/handlers/project');

const Project = require('../models/project');

exports.create = {
  validate: {
    payload: {
      name: Joi.string().required(),
      maintainers: Joi.array(),
      description: Joi.string(),
      hasLicense: Joi.boolean(),
      hasLinter: Joi.boolean(),
      hasReadme: Joi.boolean(),
      engines: {
        npm: Joi.string(),
        node: Joi.string()
      }
    }
  },
  handler: (request, reply) => {
    Project.find({ name: request.payload.name }, (err, foundProject) => {
      if (err) {
        Logger.error(`projects.find ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (foundProject.length > 0) {
        Logger.error(
          `projects.find Project ${request.payload.name} already exists`
        );
        return reply(Boom.badRequest('A project by that name already exists.'));
      }

      const payload = request.payload;
      const toCreate = {
        name: payload.name,
        maintainers: payload.maintainers || [],
        description: payload.description || '',
        hasLicense: payload.hasLicense || false,
        hasLinter: payload.hasLinter || false,
        hasReadme: payload.hasReadme || false,
        engines: {
          npm: payload.engines ? payload.engines.npm : '0.0.0',
          node: payload.engines ? payload.engines.node : '0.0.0'
        }
      };

      new Project(toCreate).save((err, newProject) => {
        if (err) {
          Logger.error(`projects.create ${err.message}`);
          return reply(Boom.badRequest(err));
        }

        reply(newProject);
      });
    });
  }
};

exports.delete = {
  validate: {
    params: {
      name: Joi.string().required()
    }
  },
  handler: (request, reply) => {
    Project.remove({ name: request.params.name }, (err, foundProject) => {
      if (err) {
        Logger.error(`projects.destroy ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (foundProject.length === 0) {
        Logger.error('projects.destroy Project not found');
        return reply(Boom.notFound('Project not found.'));
      }

      reply();
    });
  }
};

exports.getOne = {
  validate: {
    params: {
      name: Joi.string().required()
    }
  },
  handler: (request, reply) => {
    Project.findOne({
      name: request.params.name
    })
    .populate('versions')
    .exec((err, foundProject) => {
      if (err) {
        Logger.error(`projects.findOne ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (!foundProject) {
        Logger.error(
          `projects.findOne Project ${request.payload.name} not found`
        );
        return reply(Boom.badRequest('Project not found.'));
      }

      reply(foundProject);
    });
  }
};

exports.getAll = {
  handler: (request, reply) => {
    Project.find({}).populate('versions').exec((err, foundProject) => {
      if (err) {
        Logger.error(`projects.find ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      reply(foundProject);
    });
  }
};

exports.update = {
  validate: {
    params: {
      name: Joi.string().required()
    },
    payload: {
      name: Joi.string(),
      maintainers: Joi.array(),
      description: Joi.string(),
      hasLicense: Joi.boolean(),
      hasLinter: Joi.boolean(),
      hasReadme: Joi.boolean(),
      engines: {
        npm: Joi.string(),
        node: Joi.string()
      }
    }
  },
  handler: (request, reply) => {
    Project.update({
      name: request.params.name
    }, request.payload, (err, updatedProject) => {
      if (err) {
        Logger.error(`projects.findOne ${err.message}`);
        return reply(Boom.badRequest(err));
      }

      if (updatedProject.length < 1) {
        Logger.error(`projects.find Project ${request.payload.name} not found`);
        return reply(Boom.badRequest('Project not found.'));
      }

      reply(updatedProject);
    });
  }
};
<|endoftext|>


<commit_before>var _ = require('lodash');
require('colors');

describe('benchmarks', function () {

	describe('sails.load()', function() {
		before(function () {
			this.microtime = require('microtime');
			this.results = [];
		});
		after(function () {
			console.log('\n\n');
			console.log('Benchmarks::');
			var benchmarks = _.reduce(this.results, function (memo, result) {

				// Convert to ms- round to 0 decimal places
				var ms = (result.duration / 1000.0);
				ms = Math.round(ms * 1) / 1;

				var expected = this.expected || 1000;
				var color =
					(ms < expected/10) ? 'blue' :
					(ms < expected/5) ? 'cyan' :
					(ms < expected/3) ? 'yellow' :
					(ms < expected/2) ? 'orange' :
					'red';

				ms += 'ms';
				ms = ms[color];

				return memo + '\n ' +
					(result.benchmark+'').grey + ' :: ' + ms;
			},'');
			console.log(benchmarks);
		});

		benchmark('require("sails")', function(cb) {
			var sails = require('sails');
			return cb();
		});

		benchmark('first time, no hooks', function(cb) {
			var sails = require('sails');
			sails.load({
				log: { level: 'error' },
				globals: false,
				loadHooks: []
			}, cb);
		});

		benchmark('again, no hooks', function(cb) {
			var sails = require('sails');
			sails.load({
				log: { level: 'error' },
				globals: false,
				loadHooks: []
			}, cb);
		});

		benchmark('with moduleloader hook', function(cb) {
			var sails = require('sails');
			sails.load({
				log: { level: 'error' },
				globals: false,
				loadHooks: ['moduleloader']
			}, cb);
		});

	});

});

/**
 * Run the specified function, capturing time elapsed.
 *
 * @param  {[type]}   description [description]
 * @param  {Function} fn          [description]
 * @return {[type]}               [description]
 */
function benchmark (description, fn) {
	it(description, function (cb) {
		var self = this;

		var startedAt = self.microtime.now();
		// console.time(description);
		fn(function _callback () {
			// console.timeEnd(description);
			var finishedAt = self.microtime.now();
			var duration = finishedAt - startedAt;
			self.results.push({duration: duration, benchmark: description});
			cb.apply(Array.prototype.slice.call(arguments));
		});
	});
}<commit_msg>Factored out reportBenchmarks and setupBenchmarks<commit_after>
describe('benchmarks', function () {

	describe('sails.load()', function() {
		before(setupBenchmarks);
		after(reportBenchmarks);

		benchmark('require("sails")', function(cb) {
			var sails = require('sails');
			return cb();
		});

		benchmark('first time, no hooks', function(cb) {
			var sails = require('sails');
			sails.load({
				log: { level: 'error' },
				globals: false,
				loadHooks: []
			}, cb);
		});

		benchmark('again, no hooks', function(cb) {
			var sails = require('sails');
			sails.load({
				log: { level: 'error' },
				globals: false,
				loadHooks: []
			}, cb);
		});

		benchmark('with moduleloader hook', function(cb) {
			var sails = require('sails');
			sails.load({
				log: { level: 'error' },
				globals: false,
				loadHooks: ['moduleloader']
			}, cb);
		});

	});

});

/**
 * Run the specified function, capturing time elapsed.
 *
 * @param  {[type]}   description [description]
 * @param  {Function} fn          [description]
 * @return {[type]}               [description]
 */
function benchmark (description, fn) {
	it(description, function (cb) {
		var self = this;

		var startedAt = self.microtime.now();
		// console.time(description);
		fn(function _callback () {
			// console.timeEnd(description);
			var finishedAt = self.microtime.now();
			var duration = finishedAt - startedAt;
			self.benchmarks.push({duration: duration, benchmark: description});
			cb.apply(Array.prototype.slice.call(arguments));
		});
	});
}

/**
 * Use in mocha's `before`
 *
 * @this {Array} benchmarks
 * @this {Object} microtime
 */
function setupBenchmarks() {
	this.microtime = require('microtime');
	this.benchmarks = [];
}

/**
 * Use in mocha's `after`
 *
 * @this {Array} benchmarks
 * @this {Object} microtime
 */
function reportBenchmarks () {
	var _ = require('lodash');
	require('colors');
	console.log('\n\n');
	console.log('Benchmarks::');
	var benchmarks = _.reduce(this.benchmarks, function (memo, result) {

		// Convert to ms- round to 0 decimal places
		var ms = (result.duration / 1000.0);
		ms = Math.round(ms * 1) / 1;

		var expected = this.expected || 1000;
		var color =
			(ms < expected/10) ? 'blue' :
			(ms < expected/5) ? 'cyan' :
			(ms < expected/3) ? 'yellow' :
			(ms < expected/2) ? 'orange' :
			'red';

		ms += 'ms';
		ms = ms[color];

		return memo + '\n ' +
			(result.benchmark+'').grey + ' :: ' + ms;
	},'');
	console.log(benchmarks);
}<|endoftext|>


<commit_before>var push = require('pushover-notifications');
var logger = require('../log');

function run(trigger, scope, data, config, callback) {
    var pConf = data.pluginconf.Pushover;
    if (pConf && pConf.enable) {
        //ensure key has been entered before trying to push
        if (pConf.group == 0 || pConf.group == '0' || !pConf.group) {
          logger.main.error('Pushover: ' + data.address + ' No User/Group key set. Please enter User/Group Key.');
            callback();
          } else {
            var p = new push({
              user: pConf.group,
              token: config.pushAPIKEY,
            });

            var msg = {
              message: data.message,
              title: data.agency+' - '+data.alias,
              sound: pConf.sound.value,
              priority: pConf.priority.value,
              onerror: function(err) {
                logger.main.error('Pushover:', err);
                }
            };

            if (pConf.priority.value == 2 || pConf.priority.value == '2') {
              //emergency message
              msg.retry = 60;
              msg.expire = 240;
              logger.main.info("SENDING EMERGENCY PUSH NOTIFICATION")
            }

            p.send(msg, function (err, result) {
              if (err) { logger.main.error('Pushover:' + err); }
              logger.main.debug('Pushover:' + result);
              callback();
            });
          }
    } else {
        callback();
    }

}

module.exports = {
    run: run
}
<commit_msg>do the things to make bad error go away<commit_after>var push = require('pushover-notifications');
var logger = require('../log');

function run(trigger, scope, data, config, callback) {
    var pConf = data.pluginconf.Pushover;
    if (pConf && pConf.enable) {
        //ensure key has been entered before trying to push
        if (pConf.group == 0 || pConf.group == '0' || !pConf.group) {
          logger.main.error('Pushover: ' + data.address + ' No User/Group key set. Please enter User/Group Key.');
            callback();
          } else {
            var p = new push({
              user: pConf.group,
              token: config.pushAPIKEY,
            });

            var pushSound;
            if (pConf.sound) {
              pushSound = pConf.sound.value;
            }

            var pushPri = 0; // default
            if (pConf.priority) {
              pushPri = pConf.priority.value;
            }

            var msg = {
              message: data.message,
              title: data.agency+' - '+data.alias,
              sound: pushSound,
              priority: pushPri,
              onerror: function(err) {
                logger.main.error('Pushover:', err);
                }
            };

            if (pushPri == 2 || pushPri == '2') {
              //emergency message
              msg.retry = 60;
              msg.expire = 240;
              logger.main.info("SENDING EMERGENCY PUSH NOTIFICATION")
            }

            p.send(msg, function (err, result) {
              if (err) { logger.main.error('Pushover:' + err); }
              logger.main.debug('Pushover:' + result);
              callback();
            });
          }
    } else {
        callback();
    }

}

module.exports = {
    run: run
}
<|endoftext|>


<commit_before>/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-addon');

module.exports = function(defaults) {
  var app = new EmberApp(defaults, {
    // Add options here
  });

  /*
    This build file specifes the options for the dummy test app of this
    addon, located in `/tests/dummy`
    This build file does *not* influence how the addon or the app using it
    behave. You most likely want to be modifying `./index.js` or app's build file
  */

  var funnel = require('broccoli-funnel');
  var UnwatchedDir  = require('broccoli-source').UnwatchedDir;

  app.import(app.bowerDirectory + '/bootstrap-sass/assets/javascripts/bootstrap.js');

  var bootstrapFonts = funnel(app.bowerDirectory + '/bootstrap-sass/assets/fonts/bootstrap', {
    destDir: '/assets/bootstrap'
  });

  var readmeDoc = funnel(new UnwatchedDir(app.project.root), {
    files: ['README.md'],
    destDir: '/docs'
  });

  return app.toTree([bootstrapFonts, readmeDoc]);
};
<commit_msg>add babel polyfill so phantom 1.9 works<commit_after>/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-addon');

module.exports = function(defaults) {
  var app = new EmberApp(defaults, {
    babel: {
      includePolyfill: true
    }
  });

  /*
    This build file specifes the options for the dummy test app of this
    addon, located in `/tests/dummy`
    This build file does *not* influence how the addon or the app using it
    behave. You most likely want to be modifying `./index.js` or app's build file
  */

  var funnel = require('broccoli-funnel');
  var UnwatchedDir  = require('broccoli-source').UnwatchedDir;

  app.import(app.bowerDirectory + '/bootstrap-sass/assets/javascripts/bootstrap.js');

  var bootstrapFonts = funnel(app.bowerDirectory + '/bootstrap-sass/assets/fonts/bootstrap', {
    destDir: '/assets/bootstrap'
  });

  var readmeDoc = funnel(new UnwatchedDir(app.project.root), {
    files: ['README.md'],
    destDir: '/docs'
  });

  return app.toTree([bootstrapFonts, readmeDoc]);
};
<|endoftext|>


<commit_before>'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');
const shim = require('@html-next/flexi-layouts/lib/pod-templates-shim');

shim(EmberApp);

module.exports = function(defaults) {
  const app = new EmberApp(defaults, {
    'asset-cache': {
      include: [
        'assets/**/*',
        'favicons/**/*',
        'fonts/**/*',
        'img/**/*',
        'svgs/**/*'
      ]
    },
    'esw-cache-fallback': {
      patterns: [
        '/github-repos'
      ],
    },
    emberCliConcat: {
      js: {
        concat: process.env.EMBER_ENV === 'production',
        useAsync: process.env.EMBER_ENV === 'production'
      },
      css: {
        concat: false
      }
    },
    'ember-img-lazy': {
      lazyFastBoot: true,
      setSrcImmediately: true,
      observerConfig: {
        rootMargin: '100px 0px',
        threshold: 0.01
      }
    },
    fingerprint: {
      extensions: ['js', 'css', 'map']
    },
    inlineContent: {
      app: 'inline/styles/app.css',
      contact: 'inline/styles/contact.css',
      'ember-consulting': 'inline/styles/ember-consulting.css',
      fonts: 'inline/styles/fonts.css',
      'google-analytics': {
        file: 'inline/ga.js',
        enabled: process.env.EMBER_ENV === 'production'
      },
      home: 'inline/styles/home.css',
      loadCSS: 'inline/loadCSS.js',
      'loading-indicator': {
        file: 'inline/loading-indicator.html',
        enabled: false
      },
      'open-source': 'inline/styles/open-source.css'
    },
    prember: {
      urls: [
        '/',
        '/ember-consulting',
        '/open-source',
        '/contact'
      ]
    },
    SRI: {
      enabled: false
    },
    treeShaking: {
      enabled: true,
      include: [
        'ember-validators/format.js',
        'ember-validators/presence.js'
      ]
    },
    vendorFiles: { 'jquery.js': null }
  });

  return app.toTree();
};
<commit_msg>Set version to 2 to bust cache<commit_after>'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');
const shim = require('@html-next/flexi-layouts/lib/pod-templates-shim');

shim(EmberApp);

module.exports = function(defaults) {
  const app = new EmberApp(defaults, {
    'asset-cache': {
      include: [
        'assets/**/*',
        'favicons/**/*',
        'fonts/**/*',
        'img/**/*',
        'svgs/**/*'
      ],
      version: '2'
    },
    'esw-cache-fallback': {
      patterns: [
        '/github-repos'
      ],
    },
    'esw-prember': {
      version: '2'
    },
    emberCliConcat: {
      js: {
        concat: process.env.EMBER_ENV === 'production',
        useAsync: process.env.EMBER_ENV === 'production'
      },
      css: {
        concat: false
      }
    },
    'ember-img-lazy': {
      lazyFastBoot: true,
      setSrcImmediately: true,
      observerConfig: {
        rootMargin: '100px 0px',
        threshold: 0.01
      }
    },
    fingerprint: {
      extensions: ['js', 'css', 'map']
    },
    inlineContent: {
      app: 'inline/styles/app.css',
      contact: 'inline/styles/contact.css',
      'ember-consulting': 'inline/styles/ember-consulting.css',
      fonts: 'inline/styles/fonts.css',
      'google-analytics': {
        file: 'inline/ga.js',
        enabled: process.env.EMBER_ENV === 'production'
      },
      home: 'inline/styles/home.css',
      loadCSS: 'inline/loadCSS.js',
      'loading-indicator': {
        file: 'inline/loading-indicator.html',
        enabled: false
      },
      'open-source': 'inline/styles/open-source.css'
    },
    prember: {
      urls: [
        '/',
        '/ember-consulting',
        '/open-source',
        '/contact'
      ]
    },
    SRI: {
      enabled: false
    },
    treeShaking: {
      enabled: true,
      include: [
        'ember-validators/format.js',
        'ember-validators/presence.js'
      ]
    },
    vendorFiles: { 'jquery.js': null }
  });

  return app.toTree();
};
<|endoftext|>


<commit_before>
// 3rd
const debug = require('debug')('app:services:discord')
const assert = require('better-assert')
// 1st
const Client = require('../discord/client')
const config = require('../config')
const pre = require('../presenters')

//
// TODO: DRY up these functions.
// TODO: Avoid the #staff-channel lookup on every function call.
//

////////////////////////////////////////////////////////////

function makeClient () {
  return new Client({botToken: config.DISCORD_BOT_TOKEN})
}

////////////////////////////////////////////////////////////

// nuker and spambot are users
exports.broadcastManualNuke = async ({nuker, spambot}) => {
  assert(nuker)
  assert(spambot)
  pre.presentUser(nuker)
  pre.presentUser(spambot)

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  const content = `@here :doctorBUTTON: ${nuker.uname} nuked ${config.HOST}${spambot.url} :radioactive:`

  console.log(content)

  // Broadcast
  await client.createMessage(channel.id, { content })
}

////////////////////////////////////////////////////////////

// nuker and spambot are users
exports.broadcastManualUnnuke = async ({nuker, spambot}) => {
  assert(nuker)
  assert(spambot)
  pre.presentUser(nuker)
  pre.presentUser(spambot)

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  const content = `@here :white_check_mark: ${nuker.uname} UN-nuked ${config.HOST}${spambot.url}`

  // Broadcast
  await client.createMessage(channel.id, { content })
}

////////////////////////////////////////////////////////////

// Info is an object of arbitrary data about the analysis
// to be sent along with the broadcast for debugging purposes.
exports.broadcastAutoNuke = async (user, postId, info) => {
  assert(user)
  assert(Number.isInteger(postId))

  // Need url
  pre.presentUser(user)

  if (!config.IS_DISCORD_CONFIGURED) {
    console.error(`
      Called services.discord.js#broadcastAutoNuke but Discord
      is not configured.
    `)
    return
  }

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  const content = `@here :robot: User ${config.HOST}${user.url} was auto-nuked for this post: ${config.HOST}/posts/${postId} :radioactive:

\`\`\`
${JSON.stringify(info, null, 2)}
\`\`\`
  `.trim()

  // Broadcast
  await client.createMessage(channel.id, { content })
}

////////////////////////////////////////////////////////////

exports.broadcastUserJoin = async (user) => {
  // Need url
  pre.presentUser(user)

  if (!config.IS_DISCORD_CONFIGURED) {
    console.error(`
      Called services.discord.js#broadcastUserJoin but Discord
      is not configured.
    `)
    return
  }

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  // Broadcast
  await client.createMessage(channel.id, {
    content: `@here :doctorPUNK: A new user joined: ${config.HOST}${user.url}`
  })
}
<commit_msg>Tweak discord broadcasts<commit_after>
// 3rd
const debug = require('debug')('app:services:discord')
const assert = require('better-assert')
// 1st
const Client = require('../discord/client')
const config = require('../config')
const pre = require('../presenters')

//
// TODO: DRY up these functions.
// TODO: Avoid the #staff-channel lookup on every function call.
//

////////////////////////////////////////////////////////////

function makeClient () {
  return new Client({botToken: config.DISCORD_BOT_TOKEN})
}

////////////////////////////////////////////////////////////

// nuker and spambot are users
exports.broadcastManualNuke = async ({nuker, spambot}) => {
  assert(nuker)
  assert(spambot)
  pre.presentUser(nuker)
  pre.presentUser(spambot)

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  const content = `@here :button: ${nuker.uname} nuked ${config.HOST}${spambot.url} :radioactive:`

  console.log(content)

  // Broadcast
  await client.createMessage(channel.id, { content })
}

////////////////////////////////////////////////////////////

// nuker and spambot are users
exports.broadcastManualUnnuke = async ({nuker, spambot}) => {
  assert(nuker)
  assert(spambot)
  pre.presentUser(nuker)
  pre.presentUser(spambot)

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  const content = `@here :white_check_mark: ${nuker.uname} UN-nuked ${config.HOST}${spambot.url}`

  // Broadcast
  await client.createMessage(channel.id, { content })
}

////////////////////////////////////////////////////////////

// Info is an object of arbitrary data about the analysis
// to be sent along with the broadcast for debugging purposes.
exports.broadcastAutoNuke = async (user, postId, info) => {
  assert(user)
  assert(Number.isInteger(postId))

  // Need url
  pre.presentUser(user)

  if (!config.IS_DISCORD_CONFIGURED) {
    console.error(`
      Called services.discord.js#broadcastAutoNuke but Discord
      is not configured.
    `)
    return
  }

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  const content = `@here :robot: User ${config.HOST}${user.url} was auto-nuked for this post: ${config.HOST}/posts/${postId} :radioactive:

\`\`\`
${JSON.stringify(info, null, 2)}
\`\`\`
  `.trim()

  // Broadcast
  await client.createMessage(channel.id, { content })
}

////////////////////////////////////////////////////////////

exports.broadcastUserJoin = async (user) => {
  // Need url
  pre.presentUser(user)

  if (!config.IS_DISCORD_CONFIGURED) {
    console.error(`
      Called services.discord.js#broadcastUserJoin but Discord
      is not configured.
    `)
    return
  }

  const client = makeClient()

  // Find the #staff-only channel
  const channel = await client.listGuildChannels(config.DISCORD_GUILD_ID)
    .then((cs) => cs.find((c) => c.name === 'staff-only'))

  if (!channel) {
    console.error(`Could not find a #staff-only channel for broadcast.`)
    return
  }

  // Broadcast
  await client.createMessage(channel.id, {
    content: `@here :kid: A new user joined: ${config.HOST}${user.url}`
  })
}
<|endoftext|>


<commit_before>import React from 'react'
import { shallow, mount } from 'enzyme'
import { createMockStore } from 'redux-test-utils'
import MediaQuery from 'react-responsive'
import { MediaQueryWrapper, responsiveWrapper, PhoneScreen, TabletScreen,
  MobileScreen, DesktopScreen, PhoneScreenHidden, TabletScreenHidden,
  DesktopScreenHidden, MobileScreenHidden, XsScreen, XsScreenHidden, SmScreen,
  SmScreenHidden, MdScreen, MdScreenHidden, LgScreen, LgScreenHidden } from '../src'

import { breakPoints } from '../src/defaults'

const shallowWithStore = (component, store) => {
  const context = {
    store: createMockStore(store),
  }
  return shallow(component, { context })
}

const mountWithStore = (component, store) => {
  const context = {
    store: createMockStore(store),
  }
  return mount(component, { context })
}

describe('components', () => {
  const query = 'min-width: 123'
  const fakeWidth = 123
  const child =
foo

  describe('MediaQueryWrapper', () => {
    it('works', () => {
      const component = shallow(<MediaQueryWrapper />)
      expect(component).to.have.type(MediaQuery)
    })
    it('handles MediaQuery props', () => {
      const component = shallow(<MediaQueryWrapper {...{ query }} />)
      expect(component).to.have.prop('query').deep.equal(query)
    })
    it('handles fakeWidth', () => {
      const component = shallow(<MediaQueryWrapper {...{ fakeWidth, query }} />)
      expect(component).to.have.prop('values').deep.equal({ deviceWidth: fakeWidth, width: fakeWidth })
      expect(component).to.have.prop('query').deep.equal(query)
    })
    it('handles dispatch', () => {
      const dispatch = () => {}
      const component = shallow(<MediaQueryWrapper {...{ dispatch }} />)
      expect(component).to.not.have.prop('dispatch')
    })
    it('handles children', () => {
      const component = shallow(<MediaQueryWrapper>{child}</MediaQueryWrapper>)
      expect(component).to.contain(child)
    })
  })
  describe('responsiveWrapper', () => {
    const store = { responsive: { fakeWidth } }
    const Wrapped = responsiveWrapper()

    it('reads fakeWidth from redux', () => {
      const component = shallowWithStore(<Wrapped />, store)
      expect(component).to.have.prop('fakeWidth').deep.equal(fakeWidth)
    })
    it('passes other props along', () => {
      const component = shallowWithStore(<Wrapped {...{ query }} />, store)
      expect(component).to.have.prop('query').deep.equal(query)
    })
  })
  const itBehavesCorrectly = (Component, goodSize, badSize) => {
    it('renders with good size', () => {
      const store = { responsive: { fakeWidth: goodSize } }
      const rendered = mountWithStore(<Component>{child}</Component>, store)
      expect(rendered).to.contain(child)
    })
    it('does not render with bad size', () => {
      const store = { responsive: { fakeWidth: badSize } }
      const rendered = mountWithStore(<Component>{child}</Component>, store)
      expect(rendered).to.not.contain(child)
    })
  }
  describe('XsScreen', () => {
    itBehavesCorrectly(XsScreen, breakPoints.xs, breakPoints.sm)
  })
  describe('XsScreenHidden', () => {
    itBehavesCorrectly(XsScreenHidden, breakPoints.sm, breakPoints.xs)
  })
  describe('SmScreen', () => {
    itBehavesCorrectly(SmScreen, breakPoints.sm, breakPoints.md)
  })
  describe('SmScreenHidden', () => {
    itBehavesCorrectly(SmScreenHidden, breakPoints.md, breakPoints.sm)
  })
  describe('MdScreen', () => {
    itBehavesCorrectly(MdScreen, breakPoints.md, breakPoints.lg)
  })
  describe('MdScreenHidden', () => {
    itBehavesCorrectly(MdScreenHidden, breakPoints.lg, breakPoints.md)
  })
  describe('LgScreen', () => {
    itBehavesCorrectly(LgScreen, breakPoints.lg, breakPoints.md)
  })
  describe('LgScreenHidden', () => {
    itBehavesCorrectly(LgScreenHidden, breakPoints.md, breakPoints.lg)
  })
  describe('PhoneScreen', () => {
    itBehavesCorrectly(PhoneScreen, breakPoints.xs, breakPoints.sm)
  })
  describe('PhoneScreenHidden', () => {
    itBehavesCorrectly(PhoneScreenHidden, breakPoints.sm, breakPoints.xs)
  })
  describe('TabletScreen', () => {
    itBehavesCorrectly(TabletScreen, breakPoints.sm, breakPoints.md)
  })
  describe('TabletScreenHidden', () => {
    itBehavesCorrectly(TabletScreenHidden, breakPoints.md, breakPoints.sm)
  })
  describe('DesktopScreen', () => {
    itBehavesCorrectly(DesktopScreen, breakPoints.md, breakPoints.sm)
  })
  describe('DesktopScreenHidden', () => {
    itBehavesCorrectly(DesktopScreenHidden, breakPoints.sm, breakPoints.md)
  })
  describe('MobileScreen', () => {
    itBehavesCorrectly(MobileScreen, breakPoints.xs, breakPoints.md)
  })
  describe('MobileScreenHidden', () => {
    itBehavesCorrectly(MobileScreenHidden, breakPoints.md, breakPoints.sm)
  })
})
<commit_msg>add test for component prop<commit_after>import React from 'react'
import { shallow, mount } from 'enzyme'
import { createMockStore } from 'redux-test-utils'
import MediaQuery from 'react-responsive'
import { MediaQueryWrapper, responsiveWrapper, PhoneScreen, TabletScreen,
  MobileScreen, DesktopScreen, PhoneScreenHidden, TabletScreenHidden,
  DesktopScreenHidden, MobileScreenHidden, XsScreen, XsScreenHidden, SmScreen,
  SmScreenHidden, MdScreen, MdScreenHidden, LgScreen, LgScreenHidden } from '../src'

import { breakPoints } from '../src/defaults'

const shallowWithStore = (component, store) => {
  const context = {
    store: createMockStore(store),
  }
  return shallow(component, { context })
}

const mountWithStore = (component, store) => {
  const context = {
    store: createMockStore(store),
  }
  return mount(component, { context })
}

describe('components', () => {
  const query = 'min-width: 123'
  const fakeWidth = 123
  const child =
foo

  describe('MediaQueryWrapper', () => {
    it('works', () => {
      const component = shallow(<MediaQueryWrapper />)
      expect(component).to.have.type(MediaQuery)
    })
    it('defaults to div', () => {
      const component = shallow(<MediaQueryWrapper />)
      expect(component).to.have.prop('component').deep.equal('div')
    })
    it('supports other components', () => {
      const component = shallow(<MediaQueryWrapper component="p" />)
      expect(component).to.have.prop('component').deep.equal('p')
    })

    it('handles MediaQuery props', () => {
      const component = shallow(<MediaQueryWrapper {...{ query }} />)
      expect(component).to.have.prop('query').deep.equal(query)
    })
    it('handles fakeWidth', () => {
      const component = shallow(<MediaQueryWrapper {...{ fakeWidth, query }} />)
      expect(component).to.have.prop('values').deep.equal({ deviceWidth: fakeWidth, width: fakeWidth })
      expect(component).to.have.prop('query').deep.equal(query)
    })
    it('handles dispatch', () => {
      const dispatch = () => {}
      const component = shallow(<MediaQueryWrapper {...{ dispatch }} />)
      expect(component).to.not.have.prop('dispatch')
    })
    it('handles children', () => {
      const component = shallow(<MediaQueryWrapper>{child}</MediaQueryWrapper>)
      expect(component).to.contain(child)
    })
  })
  describe('responsiveWrapper', () => {
    const store = { responsive: { fakeWidth } }
    const Wrapped = responsiveWrapper()

    it('reads fakeWidth from redux', () => {
      const component = shallowWithStore(<Wrapped />, store)
      expect(component).to.have.prop('fakeWidth').deep.equal(fakeWidth)
    })
    it('passes other props along', () => {
      const component = shallowWithStore(<Wrapped {...{ query }} />, store)
      expect(component).to.have.prop('query').deep.equal(query)
    })
  })
  const itBehavesCorrectly = (Component, goodSize, badSize) => {
    it('renders with good size', () => {
      const store = { responsive: { fakeWidth: goodSize } }
      const rendered = mountWithStore(<Component>{child}</Component>, store)
      expect(rendered).to.contain(child)
    })
    it('does not render with bad size', () => {
      const store = { responsive: { fakeWidth: badSize } }
      const rendered = mountWithStore(<Component>{child}</Component>, store)
      expect(rendered).to.not.contain(child)
    })
  }
  describe('XsScreen', () => {
    itBehavesCorrectly(XsScreen, breakPoints.xs, breakPoints.sm)
  })
  describe('XsScreenHidden', () => {
    itBehavesCorrectly(XsScreenHidden, breakPoints.sm, breakPoints.xs)
  })
  describe('SmScreen', () => {
    itBehavesCorrectly(SmScreen, breakPoints.sm, breakPoints.md)
  })
  describe('SmScreenHidden', () => {
    itBehavesCorrectly(SmScreenHidden, breakPoints.md, breakPoints.sm)
  })
  describe('MdScreen', () => {
    itBehavesCorrectly(MdScreen, breakPoints.md, breakPoints.lg)
  })
  describe('MdScreenHidden', () => {
    itBehavesCorrectly(MdScreenHidden, breakPoints.lg, breakPoints.md)
  })
  describe('LgScreen', () => {
    itBehavesCorrectly(LgScreen, breakPoints.lg, breakPoints.md)
  })
  describe('LgScreenHidden', () => {
    itBehavesCorrectly(LgScreenHidden, breakPoints.md, breakPoints.lg)
  })
  describe('PhoneScreen', () => {
    itBehavesCorrectly(PhoneScreen, breakPoints.xs, breakPoints.sm)
  })
  describe('PhoneScreenHidden', () => {
    itBehavesCorrectly(PhoneScreenHidden, breakPoints.sm, breakPoints.xs)
  })
  describe('TabletScreen', () => {
    itBehavesCorrectly(TabletScreen, breakPoints.sm, breakPoints.md)
  })
  describe('TabletScreenHidden', () => {
    itBehavesCorrectly(TabletScreenHidden, breakPoints.md, breakPoints.sm)
  })
  describe('DesktopScreen', () => {
    itBehavesCorrectly(DesktopScreen, breakPoints.md, breakPoints.sm)
  })
  describe('DesktopScreenHidden', () => {
    itBehavesCorrectly(DesktopScreenHidden, breakPoints.sm, breakPoints.md)
  })
  describe('MobileScreen', () => {
    itBehavesCorrectly(MobileScreen, breakPoints.xs, breakPoints.md)
  })
  describe('MobileScreenHidden', () => {
    itBehavesCorrectly(MobileScreenHidden, breakPoints.md, breakPoints.sm)
  })
})
<|endoftext|>


<commit_before>'use strict';

//region Imports

const C = require('../lib/constants');
const config = require('../lib/config');
const res = require('./mocks/response.mock');
const req = require('./mocks/request.mock');
const middleware = require('../lib/middleware');
const factory = require('../lib/factory');
const template = require('../lib/template');
const mocha = require('mocha');
const { expect } = require('chai');
const c = require('../lib/controller');
const ph = C.route;

//endregion
//region Helpers
/**
 * Expect standard Handlebars template response
 * @param {String} name Template name
 * @returns {Object}
 */
function expectTemplate(name) {
   expect(res.httpStatus).equals(C.httpStatus.OK);
   expect(res.rendered).has.property('template', name);
   expect(res.rendered).has.property('options');
   return res.rendered.options;
}

/**
 * @param {String} path Redirection target
 */
function expectRedirect(path) {
   expect(res.redirected).to.exist;
   expect(res.redirected).has.property('status', C.httpStatus.PERMANENT_REDIRECT);
   expect(res.redirected).has.property('url', path);
}

function expectJSON() {
   expect(res.httpStatus).equals(C.httpStatus.OK);
   expect(res.headers).has.property('Content-Type', C.mimeType.JSON);
   expect(res.rendered).has.property('json');
   expect(res.rendered.json).has.property('success', true);
   expect(res.rendered.json).has.property('message');
   return res.rendered.json.message;
}

//endregion

describe('Controller', ()=> {
   before(done => {

      factory.inject.flickr = require('./mocks/flickr.mock');
      factory.buildLibrary().then(() => {
         middleware.enableStatusHelpers(req, res, ()=> {
             middleware.enableViewCache(req, res, done);
         });
      });
   });

   beforeEach(() => {
      res.reset();
      req.reset();
   });

   describe('Post', ()=> {
      it('shows latest', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST);
            expect(options).has.property('slug', 'stanley-lake-snow-hike');
            expect(options.layout).is.null;

            done();
         };
         c.post.home(req, res);
      });

      it('forwards to correct URL from Flickr set ID', done => {
         res.onEnd = ()=> {
            expectRedirect('/ruminations');
            done();
         };
         req.params[ph.POST_ID] = config.flickr.featureSets[0].id;
         c.post.providerID(req, res);
      });

      it('shows post with slug', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST);
            expect(options).has.property('title', 'Kuna Cave Fails to Impress');
            expect(options).has.property('post');
            expect(options.post).has.property('id', '72157668896453295');
            expect(options.post).has.property('isPartial', false);
            done();
         };
         req.params[ph.POST_KEY] = 'kuna-cave-fails-to-impress';
         c.post.view(req, res);
      });

      it('shows post in series', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST);
            expect(options).has.property('title', 'Brother Ride 2015');
            expect(options).has.property('post');
            expect(options.post).has.property('id', '72157658679070399');
            expect(options.post).has.property('isPartial', true);
            done();
         };
         req.params[ph.SERIES_KEY] = 'brother-ride-2015';
         req.params[ph.PART_KEY] = 'huckleberry-lookout';
         c.post.inSeries(req, res);
      });

      // it.skip('forwards old blog paths to new location', ()=> {
      //    req.params[ph.YEAR] = '2014';
      //    req.params[ph.MONTH] = '08';
      //    req.params[ph.POST_KEY] = 'post-slug';
      //    c.post.date(req, res);
      //    expect(res.redirected.status).equals(C.httpStatus.TEMP_REDIRECT);
      //    expect(res.redirected.url).equals(`http://${config.blog.domain}/${req.params[ph.YEAR]}/${req.params[ph.MONTH]}/${req.params[ph.POST_KEY]}`)
      // });
      //
      // it.skip('forwards deprecated slugs to new location', ()=> {
      //    // TODO this happens in the app route config, not controller
      //    const oldPostKey = 'great-post';
      //
      //    config.blog = {
      //       domain: 'blog.test.com',
      //       redirects: { [oldPostKey]: 'still-a-great-post' }
      //    };
      //
      //    req.params[ph.POST_KEY] = oldPostKey;
      //    c.post.view(req, res);
      //    expect(res.redirected.status).equals(C.httpStatus.PERMANENT_REDIRECT);
      //    expect(res.redirected.url).equals('/' + config.blog.redirects[oldPostKey]);
      // });
   });

   describe('Photos', ()=> {
      it('loads all photo tags', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.PHOTO_TAG);
            expect(options).has.property('alphabet', C.alphabet);
            expect(options).has.property('tags');
            expect(options.tags).to.contain.all.keys(['a','b','c']);
            done();
         };
         c.photo.tags(req, res);
      });

      it('redirects to post containing photo', done => {
         res.onEnd = ()=> {
            expectRedirect('/ruminations#8458410907');
            done();
         };
         req.params[ph.PHOTO_ID] = '8458410907';
         c.photo.inPost(req, res);
      });

      it('shows all photos with tag', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.PHOTO_SEARCH);
            expect(options).has.property('photos');
            expect(options.photos).is.instanceOf(Array);
            expect(options.photos).is.length.above(10);
            done();
         };
         req.params[ph.PHOTO_TAG] = 'horse';
         c.photo.withTag(req, res);
      });

      it('loads EXIF', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.EXIF);
            expect(options).has.property('EXIF');
            expect(options.EXIF).to.contain.all.keys(['ISO','artist','lens','model']);
            expect(options.EXIF).has.property('sanitized', true);
            done();
         };
         req.params[ph.PHOTO_TAG] = '8458410907';
         c.photo.exif(req, res);
      });
   });

   describe('Category', ()=> {
      it('renders home page for default category', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY);
            expect(options).to.contain.all.keys(['description','headerCSS','jsonLD','posts','subtitle','title']);
            done();
         };
         c.category.home(req, res);
      });

      it('renders a list of subcategories', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY_LIST);
            expect(options).to.contain.all.keys(['description','headerCSS','jsonLD','subcategories','subtitle','title']);
            done();
         };
         req.params[ph.ROOT_CATEGORY] = 'what';
         c.category.list(req, res);
      });

      it('displays category at path', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY_LIST);
            expect(options).to.contain.all.keys(['description','headerCSS','jsonLD','subcategories','subtitle','title']);
            done();
         };
         req.params[ph.ROOT_CATEGORY] = 'when';
         req.params[ph.CATEGORY] = '2016';
         c.category.list(req, res);
      });

      it('creates category menu', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY_MENU);
            expect(options).to.contain.all.keys(['description','library']);
            done();
         };
         c.category.menu(req, res);
      });
   });

   describe('Menu', ()=> {
      it('builds data for main menu', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST_MENU_DATA);
            expect(res.headers).has.property('Vary','Accept-Encoding');
            expect(options).has.property('library');
            done();
         };
         c.menu.data(req, res);
      });

      it('renders mobile menu', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.MOBILE_MENU_DATA);
            expect(options).has.property('library');
            done();
         };
         c.menu.mobile(req, res);
      });
   });

   describe('Cache', ()=> {
      const cache = require('../lib/cache');
      const post1Key = 'stanley-lake-snow-hike';
      const post2Key = 'brother-ride-2015/huckleberry-lookout';
      let oldCacheSetting;

      before(() => {
         oldCacheSetting = config.cache.views;
         config.cache.views = true;
         // add fake views to cache if not already there
         return Promise.all([
            cache.view.addIfMissing(post1Key, 'Post 1'),
            cache.view.addIfMissing(post2Key, 'Post 2'),
            cache.view.exists(post1Key),
            cache.view.exists(post2Key)
         ]).then(([,,post1Exists, post2Exists ]) => {
            expect(post1Exists).is.true;
            expect(post2Exists).is.true;
         });
      });

      it('removes cached views', done => {
         res.onEnd = ()=> {
            const msg = expectJSON();
            Promise.all([
               cache.view.exists(post1Key),
               cache.view.exists(post2Key),
            ]).then(([ post1Exists, post2Exists ]) => {
               expect(post1Exists).is.not.true;
               expect(post2Exists).is.not.true;
               done();
            });
         };
         req.body.selected = [ post1Key, post2Key ];
         c.cache.deleteView(req, res);
      });

      it('renders mobile menu', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.MOBILE_MENU_DATA);
            expect(options).has.property('library');
            done();
         };
         c.menu.mobile(req, res);
      });

      after(()=> { config.cache.views = oldCacheSetting; })
   });
});<commit_msg>resetting<commit_after>'use strict';

//region Imports

const C = require('../lib/constants');
const config = require('../lib/config');
const cache = require('../lib/cache');
const res = require('./mocks/response.mock');
const req = require('./mocks/request.mock');
const middleware = require('../lib/middleware');
const factory = require('../lib/factory');
const template = require('../lib/template');
const mocha = require('mocha');
const { expect } = require('chai');
const c = require('../lib/controller');
const ph = C.route;

//endregion
//region Helpers
/**
 * Expect standard Handlebars template response
 * @param {String} name Template name
 * @returns {Object}
 */
function expectTemplate(name) {
   expect(res.httpStatus).equals(C.httpStatus.OK);
   expect(res.rendered).has.property('template', name);
   expect(res.rendered).has.property('options');
   return res.rendered.options;
}

/**
 * @param {String} path Redirection target
 */
function expectRedirect(path) {
   expect(res.redirected).to.exist;
   expect(res.redirected).has.property('status', C.httpStatus.PERMANENT_REDIRECT);
   expect(res.redirected).has.property('url', path);
}

function expectJSON() {
   expect(res.httpStatus).equals(C.httpStatus.OK);
   expect(res.headers).has.property('Content-Type', C.mimeType.JSON);
   expect(res.rendered).has.property('json');
   expect(res.rendered.json).has.property('success', true);
   expect(res.rendered.json).has.property('message');
   return res.rendered.json.message;
}

/**
 * Run exists() method for each key and confirm it does or does not exist
 * @param {String[]} keys
 * @param {Boolean} [exists]
 * @returns {Promise}
 */
function expectInCache(keys, exists = true) {
   return Promise
      .all(keys.map(k => cache.view.exists(k)))
      // all() returns an array of outputs from each method
      .then(results => { results.forEach(r => expect(r).equals(exists)); })
}

//endregion

describe('Controller', ()=> {
   before(done => {

      factory.inject.flickr = require('./mocks/flickr.mock');
      factory.buildLibrary().then(() => {
         middleware.enableStatusHelpers(req, res, ()=> {
             middleware.enableViewCache(req, res, done);
         });
      });
   });

   beforeEach(() => {
      res.reset();
      req.reset();
   });

   describe('Post', ()=> {
      it('shows latest', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST);
            expect(options).has.property('slug', 'stanley-lake-snow-hike');
            expect(options.layout).is.null;

            done();
         };
         c.post.home(req, res);
      });

      it('forwards to correct URL from Flickr set ID', done => {
         res.onEnd = ()=> {
            expectRedirect('/ruminations');
            done();
         };
         req.params[ph.POST_ID] = config.flickr.featureSets[0].id;
         c.post.providerID(req, res);
      });

      it('shows post with slug', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST);
            expect(options).has.property('title', 'Kuna Cave Fails to Impress');
            expect(options).has.property('post');
            expect(options.post).has.property('id', '72157668896453295');
            expect(options.post).has.property('isPartial', false);
            done();
         };
         req.params[ph.POST_KEY] = 'kuna-cave-fails-to-impress';
         c.post.view(req, res);
      });

      it('shows post in series', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST);
            expect(options).has.property('title', 'Brother Ride 2015');
            expect(options).has.property('post');
            expect(options.post).has.property('id', '72157658679070399');
            expect(options.post).has.property('isPartial', true);
            done();
         };
         req.params[ph.SERIES_KEY] = 'brother-ride-2015';
         req.params[ph.PART_KEY] = 'huckleberry-lookout';
         c.post.inSeries(req, res);
      });

      // it.skip('forwards old blog paths to new location', ()=> {
      //    req.params[ph.YEAR] = '2014';
      //    req.params[ph.MONTH] = '08';
      //    req.params[ph.POST_KEY] = 'post-slug';
      //    c.post.date(req, res);
      //    expect(res.redirected.status).equals(C.httpStatus.TEMP_REDIRECT);
      //    expect(res.redirected.url).equals(`http://${config.blog.domain}/${req.params[ph.YEAR]}/${req.params[ph.MONTH]}/${req.params[ph.POST_KEY]}`)
      // });
      //
      // it.skip('forwards deprecated slugs to new location', ()=> {
      //    // TODO this happens in the app route config, not controller
      //    const oldPostKey = 'great-post';
      //
      //    config.blog = {
      //       domain: 'blog.test.com',
      //       redirects: { [oldPostKey]: 'still-a-great-post' }
      //    };
      //
      //    req.params[ph.POST_KEY] = oldPostKey;
      //    c.post.view(req, res);
      //    expect(res.redirected.status).equals(C.httpStatus.PERMANENT_REDIRECT);
      //    expect(res.redirected.url).equals('/' + config.blog.redirects[oldPostKey]);
      // });
   });

   describe('Photos', ()=> {
      it('loads all photo tags', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.PHOTO_TAG);
            expect(options).has.property('alphabet', C.alphabet);
            expect(options).has.property('tags');
            expect(options.tags).to.contain.all.keys(['a','b','c']);
            done();
         };
         c.photo.tags(req, res);
      });

      it('redirects to post containing photo', done => {
         res.onEnd = ()=> {
            expectRedirect('/ruminations#8458410907');
            done();
         };
         req.params[ph.PHOTO_ID] = '8458410907';
         c.photo.inPost(req, res);
      });

      it('shows all photos with tag', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.PHOTO_SEARCH);
            expect(options).has.property('photos');
            expect(options.photos).is.instanceOf(Array);
            expect(options.photos).is.length.above(10);
            done();
         };
         req.params[ph.PHOTO_TAG] = 'horse';
         c.photo.withTag(req, res);
      });

      it('loads EXIF', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.EXIF);
            expect(options).has.property('EXIF');
            expect(options.EXIF).to.contain.all.keys(['ISO','artist','lens','model']);
            expect(options.EXIF).has.property('sanitized', true);
            done();
         };
         req.params[ph.PHOTO_TAG] = '8458410907';
         c.photo.exif(req, res);
      });
   });

   describe('Category', ()=> {
      it('renders home page for default category', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY);
            expect(options).to.contain.all.keys(['description','headerCSS','jsonLD','posts','subtitle','title']);
            done();
         };
         c.category.home(req, res);
      });

      it('renders a list of subcategories', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY_LIST);
            expect(options).to.contain.all.keys(['description','headerCSS','jsonLD','subcategories','subtitle','title']);
            done();
         };
         req.params[ph.ROOT_CATEGORY] = 'what';
         c.category.list(req, res);
      });

      it('displays category at path', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY_LIST);
            expect(options).to.contain.all.keys(['description','headerCSS','jsonLD','subcategories','subtitle','title']);
            done();
         };
         req.params[ph.ROOT_CATEGORY] = 'when';
         req.params[ph.CATEGORY] = '2016';
         c.category.list(req, res);
      });

      it('creates category menu', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.CATEGORY_MENU);
            expect(options).to.contain.all.keys(['description','library']);
            done();
         };
         c.category.menu(req, res);
      });
   });

   describe('Menu', ()=> {
      it('builds data for main menu', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.POST_MENU_DATA);
            expect(res.headers).has.property('Vary','Accept-Encoding');
            expect(options).has.property('library');
            done();
         };
         c.menu.data(req, res);
      });

      it('renders mobile menu', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.MOBILE_MENU_DATA);
            expect(options).has.property('library');
            done();
         };
         c.menu.mobile(req, res);
      });
   });

   describe('Cache', ()=> {
      const post1Key = 'stanley-lake-snow-hike';
      const post2Key = 'brother-ride-2015/huckleberry-lookout';
      const postKeys = [ post1Key, post2Key ];
      let oldCacheSetting;

      before(() => {
         oldCacheSetting = config.cache.views;
         config.cache.views = true;
         // add fake views to cache if not already present
         return Promise.all([
            cache.view.addIfMissing(post1Key, 'Post 1'),
            cache.view.addIfMissing(post2Key, 'Post 2')
         ]).then(() => expectInCache(postKeys));
      });

      it('removes cached views', done => {
         res.onEnd = ()=> {
            const msg = expectJSON();
            expect(msg).to.include(post1Key);
            expect(msg).to.include(post2Key);
            expectInCache(postKeys, false).then(() => done());
         };
         req.body.selected = postKeys;
         c.cache.deleteView(req, res);
      });

      it('removes cached JSON', done => {
         res.onEnd = ()=> {
            const options = expectTemplate(template.page.MOBILE_MENU_DATA);
            expect(options).has.property('library');
            done();
         };
         req.body.selected = postKeys;
         c.cache.deleteJSON(req, res);
      });

      after(()=> { config.cache.views = oldCacheSetting; })
   });
});<|endoftext|>