<commit_before>'use strict'

const { xfs, newProjectPath, npmInstall, message } = require('./utils')
const simpleGit = require('simple-git')
const path = require('path')
const chalk = require('chalk')
const pad = require('left-pad')
const fs = require('fs')
const yaml = require('yamljs')
const rimraf = require('rimraf')
const mkdirp = require('mkdirp')

const choochoo = fs.readFileSync(path.resolve(__dirname, '../choo!')).toString()
function formatState (state) {
  switch (state) {
    case 'read':
      return chalk.grey.bold(pad('read', 7))
    case 'deleted':
      return chalk.magenta.bold(pad('move', 7))
    case 'modified':
      return chalk.green.bold(pad('stamp', 7))
    case undefined:
      return chalk.cyan.bold(pad('NEW', 7))
    default:
      return chalk.magenta.bold(pad(state, 7))
  }
}

module.exports = (props) => {
  const destinationPath = newProjectPath(props.projectName)
  const templateRepo = (!props.templateRepo) ? 'trainyard/template-basic' : props.templateRepo
  const generatorRootPath = path.join(destinationPath(), '.generators', '.downloaded', templateRepo.split('/').pop())
  const repo = `https://github.com/${templateRepo}.git`
  const projectPath = path.join(generatorRootPath, '_app')

  fs.access(generatorRootPath, fs.F_OK, function (err) {
    if (!err) {
      rimraf(generatorRootPath, () => {
        message(chalk.white.bold('choo') + chalk.gray(' found custom template already exists and replace it.'))
        genesis()
      })
    } else {
      mkdirp(generatorRootPath, null, genesis)
    }
  })

  function genesis () {
    // clone the template repo in the current directory
    message(chalk.gray('downloading template from', repo))

    const asyncTimeout = setTimeout(() => {
      message(chalk.red('ERROR: Connection timed out'))
      process.exit(1)
    }, 5000)

    simpleGit.clone(repo, generatorRootPath)
      .catch(() => { message(chalk.red('ERROR: Connection refused')) })
      .then(() => {
        // clear timeout
        clearTimeout(asyncTimeout)

        // compile template

        // check if choo.yaml exist
        fs.stat(path.join(projectPath, '_choo.yaml'), (err, stats) => {
          if (err || !stats.isFile()) {
            message(chalk.red.bold('_choo.yaml') + chalk.gray(' file missing in custom template.'))
            process.exit(1)
          }

          // check that the cloned repo has choo as a dependency
          // TODO: May want to use better exception handling ot perhaps just require
          // could get error if file _package.json doesnt exist, or if the JSON.parse fails
          const pkg = JSON.parse(fs.readFileSync(path.join(projectPath, '_package.json')))
          if (!pkg.dependencies || !pkg.dependencies.choo) {
            message(chalk.red.bold('choo') + chalk.gray(' was not found as a dependency of the custom template'))
            process.exit(1)
          }

          const defaults = {
            required: ['_choo.yaml']
          }

          const config = Object.assign(defaults, yaml.parse(fs.readFileSync(path.join(projectPath, '_choo.yaml'), 'utf8')))

          // now that choo.yml file is present, check which files are required
          if (config.required && config.required.length > 0) {
            config.required.forEach((req, index) => {
              fs.stat(projectPath + '/' + req, (err, stats) => {
                if (err || !stats.isFile()) {
                  message(chalk.red.bold(req) + chalk.gray(' file missing in custom template.'))
                  process.exit(1)
                } else if (index === config.required.length - 1) {
                  generateApp(projectPath, destinationPath, props, config.required)
                }
              })
            })
          }
        })
      })
  }
}

function generateApp (source, destinationPath, props, required) {
  const mv = (a, b) => xfs.move(destinationPath(a), destinationPath(b))
  const targetDirName = destinationPath().split('/').pop()
  xfs.copy(path.resolve(`${source}`, '../_generators'), destinationPath('.generators'))
  xfs.copyTpl(`${source}/**/*`, destinationPath(), props)
  if (!props.templateRepo || required.indexOf('_choo.yaml') > -1) mv('_choo.yaml', 'choo.yaml')
  if (!props.templateRepo || required.indexOf('_editorconfig') > -1) mv('_editorconfig', '.editorconfig')
  if (!props.templateRepo || required.indexOf('_gitignore') > -1) mv('_gitignore', '.gitignore')
  if (!props.templateRepo || required.indexOf('_package.json') > -1) mv('_package.json', 'package.json')

  xfs.store.each((record, i) => {
    const file = record.history[record.history.length - 1]
    if (file.indexOf('template') > -1 || file.indexOf(props.templateRepo) > -1) {
      const state = formatState('read')
      const filePath = chalk.grey.bold('[$' + file.substring(file.indexOf('template'), file.length) + ']')
      message(`${state}  ${filePath}`)
    } else if (file.indexOf(targetDirName) > -1) {
      const state = formatState(record.state)
      const filePath = chalk.white.bold(file.substring(file.indexOf(targetDirName), file.length))
      message(`${state}  ${filePath}`)
    } else {
      const state = formatState(record.state)
      const filePath = chalk.white.bold(file.split('/').pop())
      message(`${state}  ${filePath}`)
    }
  })

  message(`

${chalk.yellow('HOORAY!')}  Your application scaffold is complete!
${choochoo}
Running ${chalk.yellow.bold('npm install')} for you...

    `)
  xfs.commit(npmInstall)
}
<commit_msg>Reduce nest with then<commit_after>'use strict'

const { xfs, newProjectPath, npmInstall, message } = require('./utils')
const simpleGit = require('simple-git')
const path = require('path')
const chalk = require('chalk')
const pad = require('left-pad')
const fs = require('fs')
const yaml = require('yamljs')
const rimraf = require('rimraf')
const mkdirp = require('mkdirp')

const choochoo = fs.readFileSync(path.resolve(__dirname, '../choo!')).toString()
function formatState (state) {
  switch (state) {
    case 'read':
      return chalk.grey.bold(pad('read', 7))
    case 'deleted':
      return chalk.magenta.bold(pad('move', 7))
    case 'modified':
      return chalk.green.bold(pad('stamp', 7))
    case undefined:
      return chalk.cyan.bold(pad('NEW', 7))
    default:
      return chalk.magenta.bold(pad(state, 7))
  }
}

module.exports = (props) => {
  const destinationPath = newProjectPath(props.projectName)
  const templateRepo = (!props.templateRepo) ? 'trainyard/template-basic' : props.templateRepo
  const generatorRootPath = path.join(destinationPath(), '.generators', '.downloaded', templateRepo.split('/').pop())
  const repo = `https://github.com/${templateRepo}.git`
  const projectPath = path.join(generatorRootPath, '_app')

  fs.access(generatorRootPath, fs.F_OK, function (err) {
    if (!err) {
      rimraf(generatorRootPath, () => {
        message(chalk.white.bold('choo') + chalk.gray(' found custom template already exists and replace it.'))
        genesis()
      })
    } else {
      mkdirp(generatorRootPath, null, genesis)
    }
  })

  function genesis () {
    // clone the template repo in the current directory
    message(chalk.gray('downloading template from', repo))

    const asyncTimeout = setTimeout(() => {
      message(chalk.red('ERROR: Connection timed out'))
      process.exit(1)
    }, 5000)

    simpleGit
      .clone(repo, generatorRootPath)
      .catch(() => {
        message(chalk.red('ERROR: Connection refused'))
      }).then(() => {
        // clear timeout
        clearTimeout(asyncTimeout)

        // check if choo.yaml exist
        fs.stat(path.join(projectPath, '_choo.yaml'), (err, stats) => {
          if (err || !stats.isFile()) {
            message(chalk.red.bold('_choo.yaml') + chalk.gray(' file missing in custom template.'))
            process.exit(1)
          }
        })
      }).then(() => {
        // check that the cloned repo has choo as a dependency
        // TODO: May want to use better exception handling ot perhaps just require
        // could get error if file _package.json doesnt exist, or if the JSON.parse fails
        const pkg = JSON.parse(fs.readFileSync(path.join(projectPath, '_package.json')))
        if (!pkg.dependencies || !pkg.dependencies.choo) {
          message(chalk.red.bold('choo') + chalk.gray(' was not found as a dependency of the custom template'))
          process.exit(1)
        }
      }).then(() => {
        const defaults = {
          required: ['_choo.yaml']
        }

        const config = Object.assign(defaults, yaml.parse(fs.readFileSync(path.join(projectPath, '_choo.yaml'), 'utf8')))

        // now that choo.yml file is present, check which files are required
        if (config.required && config.required.length > 0) {
          config.required.forEach((req, index) => {
            fs.stat(projectPath + '/' + req, (err, stats) => {
              if (err || !stats.isFile()) {
                message(chalk.red.bold(req) + chalk.gray(' file missing in custom template.'))
                process.exit(1)
              } else if (index === config.required.length - 1) {
                generateApp(projectPath, destinationPath, props, config.required)
              }
            })
          })
        }
      })
  }
}

function generateApp (source, destinationPath, props, required) {
  const mv = (a, b) => xfs.move(destinationPath(a), destinationPath(b))
  const targetDirName = destinationPath().split('/').pop()
  xfs.copy(path.resolve(`${source}`, '../_generators'), destinationPath('.generators'))
  xfs.copyTpl(`${source}/**/*`, destinationPath(), props)
  if (!props.templateRepo || required.indexOf('_choo.yaml') > -1) mv('_choo.yaml', 'choo.yaml')
  if (!props.templateRepo || required.indexOf('_editorconfig') > -1) mv('_editorconfig', '.editorconfig')
  if (!props.templateRepo || required.indexOf('_gitignore') > -1) mv('_gitignore', '.gitignore')
  if (!props.templateRepo || required.indexOf('_package.json') > -1) mv('_package.json', 'package.json')

  xfs.store.each((record, i) => {
    const file = record.history[record.history.length - 1]
    if (file.indexOf('template') > -1 || file.indexOf(props.templateRepo) > -1) {
      const state = formatState('read')
      const filePath = chalk.grey.bold('[$' + file.substring(file.indexOf('template'), file.length) + ']')
      message(`${state}  ${filePath}`)
    } else if (file.indexOf(targetDirName) > -1) {
      const state = formatState(record.state)
      const filePath = chalk.white.bold(file.substring(file.indexOf(targetDirName), file.length))
      message(`${state}  ${filePath}`)
    } else {
      const state = formatState(record.state)
      const filePath = chalk.white.bold(file.split('/').pop())
      message(`${state}  ${filePath}`)
    }
  })

  message(`

${chalk.yellow('HOORAY!')}  Your application scaffold is complete!
${choochoo}
Running ${chalk.yellow.bold('npm install')} for you...

    `)
  xfs.commit(npmInstall)
}
<|endoftext|>


<commit_before>'use strict';
var stampit = require('../stampit'),
  test = require('tape'),
  isArray = require('lodash/lang/isArray');

// Closure arguments

test('stamp.init() arguments are passed', function (t) {
  var stamp = stampit().init(function (opts) {
    t.ok(opts, 'opts should be passed to init()');
    t.ok(opts.instance, 'opts.instance should exist');
    t.equal(typeof opts.instance, 'object', 'opts.instance should be object');
    t.ok(opts.stamp, 'opts.stamp should exist');
    t.equal(typeof opts.stamp, 'function', 'opts.stamp should be function');
    t.ok(opts.args, 'opts.args should exist');
    t.ok(isArray(opts.args), 'opts.args should be array');
  });

  stamp();

  t.end();
});

test('stamp.init() should assign `this` to `opts.instance`', function (t) {
  var stamp = stampit().init(function (opts) {
    t.ok(opts.instance === this, 'opts.instance should equal `this`');
  });

  stamp();

  t.end();
});

test('stamp.init() should assign stamp to `opts.stamp`', function (t) {
  var stamp = stampit().init(function (opts) {
    t.ok(opts.stamp === stamp, 'opts.stamp should equal stamp');
  });

  stamp();

  t.end();
});

test('stamp.init() should assign arguments to `opts.args`', function (t) {
  var stamp = stampit().init(function (opts) {
    t.equal(opts.args[0], 'arg1', 'opts.args should equal arguments');
    t.equal(opts.args[1], undefined, 'opts.args should equal arguments');
    t.equal(opts.args[2], 'arg3', 'opts.args should equal arguments');
  });

  stamp({}, 'arg1', undefined, 'arg3');

  t.end();
});
<commit_msg>init tests added test for order init functions are called added test for stamp and opts.instace match<commit_after>'use strict';
var stampit = require('../stampit'),
  test = require('tape'),
  isArray = require('lodash/lang/isArray');

// Closure arguments

test('stamp.init() arguments are passed', function (t) {

  var initStamp;
  var stamp = stampit().init(function (opts) {
    t.ok(opts, 'opts should be passed to init()');
    t.ok(opts.instance, 'opts.instance should exist');
    t.equal(typeof opts.instance, 'object', 'opts.instance should be object');
    t.strictEqual(opts.instance, this, 'opts.instance === this');
    t.ok(opts.stamp, 'opts.stamp should exist');
    t.equal(typeof opts.stamp, 'function', 'opts.stamp should be function');
    t.ok(opts.args, 'opts.args should exist');
    t.ok(isArray(opts.args), 'opts.args should be array');
    initStamp = opts.stamp;
  });

  stamp();

  t.strictEqual(stamp, initStamp, 'opts.stamp === stamp returned');

  t.end();
});

test('stamp.init() should assign `this` to `opts.instance`', function (t) {
  var stamp = stampit().init(function (opts) {
    t.ok(opts.instance === this, 'opts.instance should equal `this`');
  });

  stamp();

  t.end();
});

test('stamp.init() should assign stamp to `opts.stamp`', function (t) {
  var stamp = stampit().init(function (opts) {
    t.ok(opts.stamp === stamp, 'opts.stamp should equal stamp');
  });

  stamp();

  t.end();
});

test('stamp.init() should assign arguments to `opts.args`', function (t) {
  var stamp = stampit().init(function (opts) {
    t.equal(opts.args[0], 'arg1', 'opts.args should equal arguments');
    t.equal(opts.args[1], undefined, 'opts.args should equal arguments');
    t.equal(opts.args[2], 'arg3', 'opts.args should equal arguments');
  });

  stamp({}, 'arg1', undefined, 'arg3');

  t.end();
});

test('stamp.init() can handle multiple init functions', function (t) {

    var init1;
    var init2;
    var init3;

    var stamp = stampit()
        .init(function () {
            init1 = true;
        }).init(function () {
            init2 = true;
        }).init(function () {
            init3 = true;
        });

    stamp();

    t.ok(init1, 'init 1 fired');
    t.ok(init2, 'init 2 fired');
    t.ok(init3, 'init 3 fired');

  t.end();
});

test('stamp.init() can handle multiple init functions assigned with array', function (t) {

    var init1;
    var init2;
    var init3;

    var stamp = stampit().init([
        function () {
            init1 = true;
        },
        function () {
            init2 = true;
        },
        function () {
            init3 = true;
        }
    ]);

    stamp();

    t.ok(init1, 'init 1 fired');
    t.ok(init2, 'init 2 fired');
    t.ok(init3, 'init 3 fired');

  t.end();
});

test('stamp.init() can handle multiple init functions assigned with object', function (t) {

    var init1;
    var init2;
    var init3;

    var stamp = stampit().init({
        foo: function () {
            init1 = true;
        },
        bar: function () {
            init2 = true;
        },
        bam: function () {
            init3 = true;
        }
    });

    stamp();

    t.ok(init1, 'init 1 fired');
    t.ok(init2, 'init 2 fired');
    t.ok(init3, 'init 3 fired');

  t.end();
});

test('stamp.init() should call composed init functions in order', function (t) {

    var result = [];

    var stamp = stampit().init(function () {
        result.push('a');
    }).init(function () {
        result.push('b');
    }).init(function () {
        result.push('c');
    });

    var stamp2 = stampit().init([
        function(){
            result.push('d');
        },
        function(){
            result.push('e');
        }
    ]);

    var stamp3 = stampit.compose(stamp, stamp2);

    stamp3();
    t.deepEqual(result, ['a', 'b', 'c', 'd', 'e'], 'init called in order');

  t.end();
});
<|endoftext|>


<commit_before>import Promise from 'bluebird';
import app from '../server/index';
import async from 'async';
import { expect } from 'chai';
import request from 'supertest';
import * as utils from '../test/utils';
import sinon from 'sinon';
import models from '../server/models';
import paypalMock from './mocks/paypal';
import paypalAdaptive from '../server/paymentProviders/paypal/adaptiveGateway';

const application = utils.data('application');

describe('paypal.preapproval.routes.test.js', () => {
  let user, user2, sandbox;

  before(() => {
    sandbox = sinon.createSandbox();
  });

  after(() => sandbox.restore());

  // Create a stub for clearbit
  beforeEach(done => {
    utils.clearbitStubBeforeEach(sandbox);
    done();
  });

  beforeEach(() => {
    sinon.stub(paypalAdaptive, 'preapproval').callsFake(() => Promise.resolve(paypalMock.adaptive.preapproval));
  });

  afterEach(() => {
    paypalAdaptive.preapproval.restore();
  });

  afterEach(() => {
    utils.clearbitStubAfterEach(sandbox);
  });

  beforeEach(done => {
    async.auto(
      {
        resetDB: cb => {
          utils.resetTestDB().asCallback(cb);
        },
        createUserA: [
          'resetDB',
          cb => {
            models.User.createUserWithCollective(utils.data('user1'))
              .then(user => cb(null, user))
              .catch(cb);
          },
        ],
        createUserB: [
          'createUserA',
          cb => {
            models.User.createUserWithCollective(utils.data('user2'))
              .then(user => cb(null, user))
              .catch(cb);
          },
        ],
      },
      (e, results) => {
        expect(e).to.not.exist;
        user = results.createUserA;
        user2 = results.createUserB;
        done();
      },
    );
  });

  /**
   * Get the preapproval Key.
   */
  describe('#getPreapprovalKey', () => {
    it('should fail if not the logged-in user', done => {
      request(app)
        .get(
          `/connected-accounts/paypal/oauthUrl?api_key=${application.api_key}&CollectiveId=${
            user.CollectiveId
          }&redirect=https://`,
        )
        .set('Authorization', `Bearer ${user2.jwt()}`)
        .expect(401)
        .end(done);
    });

    it('should get a preapproval key', done => {
      request(app)
        .get(
          `/connected-accounts/paypal/oauthUrl?api_key=${application.api_key}&CollectiveId=${
            user.CollectiveId
          }&redirect=${encodeURIComponent('https://localhost:3030/paypal/redirect')}`,
        )
        .set('Authorization', `Bearer ${user.jwt()}`)
        .expect(200)
        .end((e, res) => {
          expect(e).to.not.exist;
          expect(res.body.redirectUrl).to.contain('&preapprovalkey=PA-');
          models.PaymentMethod.findAndCountAll({ where: { service: 'paypal' } })
            .then(res => {
              expect(res.count).to.equal(1);
              const paykey = res.rows[0];
              expect(paykey).to.have.property('service', 'paypal');
              expect(paykey).to.have.property('CreatedByUserId', user.id);
              expect(paykey).to.have.property('CollectiveId', user.CollectiveId);
              expect(paykey).to.have.property('token', paypalMock.adaptive.preapproval.preapprovalKey);
              done();
            })
            .catch(done);
        });
    });
  });

  /**
   * Confirm a preapproval.
   */
  describe('#confirmPreapproval', () => {
    const preapprovalkey = paypalMock.adaptive.preapproval.preapprovalKey;

    beforeEach('get preapproval key', done => {
      request(app)
        .get(
          `/connected-accounts/paypal/oauthUrl?api_key=${application.api_key}&CollectiveId=${
            user.CollectiveId
          }&redirect=${encodeURIComponent('https://localhost:3030/paypal/redirect')}`,
        )
        .set('Authorization', `Bearer ${user.jwt()}`)
        .expect(200)
        .end(done);
    });

    describe('Details from Paypal COMPLETED', () => {
      beforeEach('stub paypalAdaptive', () => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.completed));
      });

      afterEach('restore paypalAdaptive', () => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should fail with an unknown preapproval key', done => {
        request(app)
          .get('/connected-accounts/paypal/callback?preapprovalKey=abc&paypalApprovalStatus=success')
          .set('Authorization', `Bearer ${user.jwt()}`)
          .end((e, res) => {
            const error = res.body.error;
            expect(error.code).to.equal(400);
            expect(error.message).to.equal('No paymentMethod found with this preapproval key: abc');
            done();
          });
      });

      it('should confirm the payment of a transaction', done => {
        const mock = paypalMock.adaptive.preapprovalDetails;
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .expect(302)
          .end((e, res) => {
            expect(res.headers.location).to.include('paypal/redirect?status=success&service=paypal');

            models.PaymentMethod.findAndCountAll({
              where: { token: preapprovalkey },
            })
              .then(res => {
                expect(res.count).to.equal(1);
                expect(res.rows[0].confirmedAt).not.to.be.null;
                expect(res.rows[0].service).to.equal('paypal');
                expect(res.rows[0].name).to.equal(mock.completed.senderEmail);
                expect(res.rows[0].CreatedByUserId).to.equal(user.id);
              })
              .then(() =>
                models.Activity.findAndCountAll({
                  where: { type: 'user.paymentMethod.created' },
                }),
              )
              .then(res => {
                expect(res.count).to.equal(1);
                done();
              });
          });
      });
    });

    describe('Details from Paypal CREATED', () => {
      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.created));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should return an error if the preapproval is not completed', done => {
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .end((e, res) => {
            expect(res.headers.location).to.contain(
              'paypal/redirect?status=error&service=paypal&error=Error%20while%20contacting%20PayPal&errorMessage=This%20preapprovalkey%20is%20not%20approved%20yet',
            );
            done();
          });
      });
    });

    describe('Details from Paypal ERROR', () => {
      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.reject(paypalMock.adaptive.preapprovalDetails.error));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should return an error if paypal returns one', done => {
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .end((e, res) => {
            expect(res.headers.location).to.contain(
              '/paypal/redirect?status=error&service=paypal&error=Error%20while%20contacting%20PayPal',
            );
            done();
          });
      });
    });

    describe('Preapproval details', () => {
      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.completed));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should return the preapproval details', done => {
        request(app)
          .get(`/connected-accounts/paypal/verify?preapprovalKey=${preapprovalkey}&api_key=${application.api_key}`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .expect(200)
          .end((e, res) => {
            expect(res.body.data.response.approved).to.equal('true');
            done();
          });
      });

      it('should not be able to check another user preapproval details', done => {
        request(app)
          .get(`/connected-accounts/paypal/verify?preapprovalKey=${preapprovalkey}&api_key=${application.api_key}`)
          .set('Authorization', `Bearer ${user2.jwt()}`)
          .expect(401)
          .end(done);
      });
    });

    describe('PaymentMethods clean up', () => {
      // create another dummy payment method for this user
      beforeEach(() => {
        return models.PaymentMethod.create({
          service: 'paypal',
          type: 'adaptive',
          CreatedByUserId: user.id,
          CollectiveId: user.CollectiveId,
          token: 'blah',
        });
      });

      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.completed));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should delete all other paymentMethods entries in the database to clean up', done => {
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .expect(302)
          .end(e => {
            expect(e).to.not.exist;
            models.PaymentMethod.findAndCountAll({
              where: { token: preapprovalkey },
            }).then(res => {
              expect(res.count).to.equal(1);
              expect(res.rows[0].confirmedAt).not.to.be.null;
              expect(res.rows[0].service).to.equal('paypal');
              expect(res.rows[0].CreatedByUserId).to.equal(user.id);
              done();
            });
          });
      });
    });
  });
});
<commit_msg>fix test<commit_after>import Promise from 'bluebird';
import app from '../server/index';
import async from 'async';
import { expect } from 'chai';
import request from 'supertest';
import * as utils from '../test/utils';
import sinon from 'sinon';
import models from '../server/models';
import paypalMock from './mocks/paypal';
import paypalAdaptive from '../server/paymentProviders/paypal/adaptiveGateway';

const application = utils.data('application');

describe('paypal.preapproval.routes.test.js', () => {
  let user, user2, sandbox;

  before(() => {
    sandbox = sinon.createSandbox();
  });

  after(() => sandbox.restore());

  // Create a stub for clearbit
  beforeEach(done => {
    utils.clearbitStubBeforeEach(sandbox);
    done();
  });

  beforeEach(() => {
    sinon.stub(paypalAdaptive, 'preapproval').callsFake(() => Promise.resolve(paypalMock.adaptive.preapproval));
  });

  afterEach(() => {
    paypalAdaptive.preapproval.restore();
  });

  afterEach(() => {
    utils.clearbitStubAfterEach(sandbox);
  });

  beforeEach(done => {
    async.auto(
      {
        resetDB: cb => {
          utils.resetTestDB().asCallback(cb);
        },
        createUserA: [
          'resetDB',
          cb => {
            models.User.createUserWithCollective(utils.data('user1'))
              .then(user => cb(null, user))
              .catch(cb);
          },
        ],
        createUserB: [
          'createUserA',
          cb => {
            models.User.createUserWithCollective(utils.data('user2'))
              .then(user => cb(null, user))
              .catch(cb);
          },
        ],
      },
      (e, results) => {
        expect(e).to.not.exist;
        user = results.createUserA;
        user2 = results.createUserB;
        done();
      },
    );
  });

  /**
   * Get the preapproval Key.
   */
  describe('#getPreapprovalKey', () => {
    it('should fail if not the logged-in user', done => {
      request(app)
        .get(
          `/connected-accounts/paypal/oauthUrl?api_key=${application.api_key}&CollectiveId=${
            user.CollectiveId
          }&redirect=https://`,
        )
        .set('Authorization', `Bearer ${user2.jwt()}`)
        .expect(401)
        .end(done);
    });

    it('should get a preapproval key', done => {
      request(app)
        .get(
          `/connected-accounts/paypal/oauthUrl?api_key=${application.api_key}&CollectiveId=${
            user.CollectiveId
          }&redirect=${encodeURIComponent('https://localhost:3030/paypal/redirect')}`,
        )
        .set('Authorization', `Bearer ${user.jwt()}`)
        .expect(200)
        .end((e, res) => {
          expect(e).to.not.exist;
          expect(res.body.redirectUrl).to.contain('&preapprovalkey=PA-');
          models.PaymentMethod.findAndCountAll({ where: { service: 'paypal' } })
            .then(res => {
              expect(res.count).to.equal(1);
              const paykey = res.rows[0];
              expect(paykey).to.have.property('service', 'paypal');
              expect(paykey).to.have.property('CreatedByUserId', user.id);
              expect(paykey).to.have.property('CollectiveId', user.CollectiveId);
              expect(paykey).to.have.property('token', paypalMock.adaptive.preapproval.preapprovalKey);
              done();
            })
            .catch(done);
        });
    });
  });

  /**
   * Confirm a preapproval.
   */
  describe('#confirmPreapproval', () => {
    const preapprovalkey = paypalMock.adaptive.preapproval.preapprovalKey;

    beforeEach('get preapproval key', done => {
      request(app)
        .get(
          `/connected-accounts/paypal/oauthUrl?api_key=${application.api_key}&CollectiveId=${
            user.CollectiveId
          }&redirect=${encodeURIComponent('https://localhost:3030/paypal/redirect')}`,
        )
        .set('Authorization', `Bearer ${user.jwt()}`)
        .expect(200)
        .end(done);
    });

    describe('Details from Paypal COMPLETED', () => {
      beforeEach('stub paypalAdaptive', () => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.completed));
      });

      afterEach('restore paypalAdaptive', () => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should fail with an unknown preapproval key', done => {
        request(app)
          .get('/connected-accounts/paypal/callback?preapprovalKey=abc&paypalApprovalStatus=success')
          .set('Authorization', `Bearer ${user.jwt()}`)
          .end((e, res) => {
            const error = res.body.error;
            expect(error.code).to.equal(400);
            expect(error.message).to.equal('No paymentMethod found with this preapproval key: abc');
            done();
          });
      });

      it('should confirm the payment of a transaction', done => {
        const mock = paypalMock.adaptive.preapprovalDetails;
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .expect(302)
          .end((e, res) => {
            expect(res.headers.location).to.include('paypal/redirect?status=success&service=paypal');

            models.PaymentMethod.findAndCountAll({
              where: { token: preapprovalkey },
            })
              .then(res => {
                expect(res.count).to.equal(1);
                expect(res.rows[0].confirmedAt).not.to.be.null;
                expect(res.rows[0].service).to.equal('paypal');
                expect(res.rows[0].name).to.equal(mock.completed.senderEmail);
                expect(res.rows[0].CreatedByUserId).to.equal(user.id);
              })
              .then(() =>
                models.Activity.findAndCountAll({
                  where: { type: 'user.paymentMethod.created' },
                }),
              )
              .then(res => {
                expect(res.count).to.equal(1);
                done();
              });
          });
      });
    });

    describe('Details from Paypal CREATED', () => {
      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.created));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should return an error if the preapproval is not completed', done => {
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .end((e, res) => {
            expect(res.headers.location).to.contain(
              'paypal/redirect?status=error&service=paypal&error=Error%20while%20contacting%20PayPal&errorMessage=This%20preapprovalkey%20is%20not%20approved%20yet',
            );
            done();
          });
      });
    });

    describe('Details from Paypal ERROR', () => {
      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.reject(paypalMock.adaptive.preapprovalDetails.error));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should return an error if paypal returns one', done => {
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .end((e, res) => {
            expect(res.headers.location).to.contain(
              '/paypal/redirect?status=error&service=paypal&error=Error%20while%20contacting%20PayPal',
            );
            done();
          });
      });
    });

    describe('Preapproval details', () => {
      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.completed));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should return the preapproval details', done => {
        request(app)
          .get(`/connected-accounts/paypal/verify?preapprovalKey=${preapprovalkey}&api_key=${application.api_key}`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .expect(200)
          .end((e, res) => {
            expect(res.body.data.details.approved).to.equal('true');
            done();
          });
      });

      it('should not be able to check another user preapproval details', done => {
        request(app)
          .get(`/connected-accounts/paypal/verify?preapprovalKey=${preapprovalkey}&api_key=${application.api_key}`)
          .set('Authorization', `Bearer ${user2.jwt()}`)
          .expect(401)
          .end(done);
      });
    });

    describe('PaymentMethods clean up', () => {
      // create another dummy payment method for this user
      beforeEach(() => {
        return models.PaymentMethod.create({
          service: 'paypal',
          type: 'adaptive',
          CreatedByUserId: user.id,
          CollectiveId: user.CollectiveId,
          token: 'blah',
        });
      });

      beforeEach(() => {
        sinon
          .stub(paypalAdaptive, 'preapprovalDetails')
          .callsFake(() => Promise.resolve(paypalMock.adaptive.preapprovalDetails.completed));
      });

      afterEach(() => {
        paypalAdaptive.preapprovalDetails.restore();
      });

      it('should delete all other paymentMethods entries in the database to clean up', done => {
        request(app)
          .get(`/connected-accounts/paypal/callback?preapprovalKey=${preapprovalkey}&paypalApprovalStatus=success`)
          .set('Authorization', `Bearer ${user.jwt()}`)
          .expect(302)
          .end(e => {
            expect(e).to.not.exist;
            models.PaymentMethod.findAndCountAll({
              where: { token: preapprovalkey },
            }).then(res => {
              expect(res.count).to.equal(1);
              expect(res.rows[0].confirmedAt).not.to.be.null;
              expect(res.rows[0].service).to.equal('paypal');
              expect(res.rows[0].CreatedByUserId).to.equal(user.id);
              done();
            });
          });
      });
    });
  });
});
<|endoftext|>


<commit_before>import HidingSpot from './HidingSpot'

class HidingSpots extends React.Component {
  renderGameBoard() {
    return this.props.game.hidingSpots.edges.map(edge => (
      <HidingSpot
        game={this.props.game}
        hidingSpot={edge.node}
      />
    ));
  }

  _handleHidingSpotPageClick() {
    if (this.props.game.hidingSpots.pageInfo.hasNextPage) {
      this.props.relay.setVariables({
        hidingSpotCursor: this.props.game.hidingSpots.pageInfo.endCursor,
      });
    } else {
      this.props.relay.setVariables({
        hidingSpotCursor: null,
      });
    }
  }

  renderCursorButtons() {
    return (

        <button
          onClick={this._handleHidingSpotPageClick.bind(this)}>
          Page
        </button>

    );
  }

  render() {
    return (

        {this.renderGameBoard()}
        {this.renderCursorButtons()}

    );
  }
}

export default Relay.createContainer(HidingSpots, {
  initialVariables: {
    hidingSpotCursor: null
  },
  fragments: {
    game: () => Relay.QL`
      fragment on Game {
        hidingSpots(first: 3 after: $hidingSpotCursor) {
          edges {
            node {
              ${HidingSpot.getFragment('hidingSpot')},
            },
            cursor,
          },
          pageInfo {
            hasNextPage,
            endCursor,
          },
        },
        ${HidingSpot.getFragment('game')},
      }
    `,
  }
})
<commit_msg>Working on forward backward pagination<commit_after>import HidingSpot from './HidingSpot'

class HidingSpots extends React.Component {
  renderGameBoard() {
    return this.props.game.hidingSpots.edges.map(edge => (
      <HidingSpot
        game={this.props.game}
        hidingSpot={edge.node}
      />
    ));
  }

  _handleHidingSpotNextPageClick() {
    this.props.relay.setVariables({
      first: 3,
      afterHidingSpotCursor: this.props.game.hidingSpots.pageInfo.endCursor,
      last: null,
      beforeHidingSpotCursor: null,
    });
  }

  _handleHidingSpotPreviousPageClick() {
    this.props.relay.setVariables({
      first: null,
      afterHidingSpotCursor: null,
      last: 3,
      beforeHidingSpotCursor: this.props.game.hidingSpots.pageInfo.startCursor,
    });
  }

  renderCursorButtons() {
    return (

        <button
          disabled={!this.props.game.hidingSpots.pageInfo.hasPreviousPage}
          onClick={this._handleHidingSpotPreviousPageClick.bind(this)}>
          backward
        </button>
        <button
          disabled={!this.props.game.hidingSpots.pageInfo.hasNextPage}
          onClick={this._handleHidingSpotNextPageClick.bind(this)}>
          forward
        </button>

    );
  }

  render() {
    return (

        {this.renderGameBoard()}
        {this.renderCursorButtons()}

    );
  }
}

export default Relay.createContainer(HidingSpots, {
  initialVariables: {
    first: 3,
    afterHidingSpotCursor: null,
    last: null,
    beforeHidingSpotCursor: null,
  },
  fragments: {
    game: () => Relay.QL`
      fragment on Game {
        hidingSpots(
          first: $first
          after: $afterHidingSpotCursor
          last:  $last
          before: $beforeHidingSpotCursor
        ) {
          edges {
            node {
              ${HidingSpot.getFragment('hidingSpot')},
            },
            cursor,
          },
          pageInfo {
            hasNextPage,
            hasPreviousPage,
            endCursor,
            startCursor,
          },
        },
        ${HidingSpot.getFragment('game')},
      }
    `,
  }
})
<|endoftext|>


<commit_before>// copy this file to ./keys.mine.js and replace the id and secret
exports.id = 'YOUR_ID';
exports.secret = 'YOUR_KEY';
exports.endpoint = 'YOUR_ENDPOINT';

<commit_msg>Added region parameter to test conf<commit_after>// Copy this file to ./keys.mine.js and replace the id and secret
// For Local DynamoDB define endpoint will be "http://localhost:8000"
exports.id = 'YOUR_ID';
exports.secret = 'YOUR_KEY';
exports.endpoint = 'YOUR_ENDPOINT';
exports.region = "eu-west-1";
<|endoftext|>


<commit_before>/*
 * grunt
 * https://github.com/cowboy/grunt
 *
 * Copyright (c) 2012 "Cowboy" Ben Alman
 * Licensed under the MIT license.
 * http://benalman.com/about/license/
 */

var path = require('path');

// Perhaps, someday, this will be the only global.
global.grunt = {};

// Used to require grunt libs. Sweet, sugary goodness. Mmmmn.
grunt.require = function(libname) { return require(path.join(__dirname, 'grunt', libname)); };

// External libs, exposed globally for convenience.
global.async = require('async');
global.underscore = require('underscore');

// Internal grunt libs, exposed globally for convenience.
global.util = grunt.require('util');
global.task = grunt.require('task');
global.file = grunt.require('file');
global.fail = grunt.require('fail');
global.config = grunt.require('config');
global.option = grunt.require('option');
global.template = grunt.require('template');
global.log = grunt.require('log');
global.verbose = log.verbose;

grunt.version = file.readJson(path.join(__dirname, '../package.json')).version;
exports.version = grunt.version;

// Handle exceptions.
process.on('uncaughtException', function (e) {
  fail.warn(e, 3);
});

// Disable colors if --no-colors was passed.
function initColors() {
  var methods = Object.keys(String.prototype);
  // Requiring this here will modify String prototype everywhere.
  require('colors');

  // Disable colors.
  if (option('no-color')) {
    // Override "colors".
    Object.keys(String.prototype).filter(function(method) {
      // Filter out methods that existed before "colors" was required.
      return methods.indexOf(method) === -1;
    }).forEach(function(method) {
      // Replace each new method with a function that just returns `this`.
      String.prototype.__defineGetter__(method, function() { return this; });
    });

    // Override console.log (nodeunit, maybe others).
    console._log = console.log;
    console.log = function() {
      var args = util.toArray(arguments).map(function(value) {
        if (typeof value === 'string') {
          return value.replace(/\033\[[\d;]+m/g, '');
        }
        return value;
      });
      console._log.apply(console, args);
    };
  }
}

// Expose the task interface. I've never called this manually, and have no idea
// how it will work. But it might.
exports.tasks = function(tasks, options, done) {
  // Update options with passed-in options.
  option.init(options);

  // Init colors.
  initColors();

  if (option('help')) {
    // Load and display help if the user did --help.
    grunt.require('help');
  } else if (option('version')) {
    // Display the current grunt version if the user did --version.
    log.writeln('grunt v' + grunt.version);
    return;
  }

  // A little header stuff.
  verbose.header('Initializing').writeflags(option.flags(), 'Command-line options');

  // Determine and output which tasks will be run.
  var tasksSpecified = tasks && tasks.length > 0;
  tasks = task.parseArgs([tasksSpecified ? tasks : 'default']);

  // Initialize tasks.
  task.init(tasks);

  verbose.writeln();
  if (!tasksSpecified) {
    verbose.writeln('No tasks specified, running default tasks.');
  }
  verbose.writeflags(tasks, 'Running tasks');

  // Report, etc when all tasks have completed.
  task.options({
    error: function(e) {
      fail.warn(e, 3);
    },
    done: function() {
      // Output a final fail / success report.
      fail.report();

      if (done) {
        // Execute "done" function when done (only if passed, of course).
        done();
      } else {
        // Otherwise, explicitly exit.
        process.exit(0);
      }
    }
  });

  // Execute all tasks, in order. Passing each task individually in a forEach
  // allows the error callback to execute multiple times.
  tasks.forEach(function(name) { task.run(name); });
  task.start();
};

// This is only executed when run via command line.
exports.cli = function(options) {
  // Parse task list and options from the command line.
  var cli = grunt.require('cli');

  // CLI-parsed options override any passed-in "default" options.
  underscore.defaults(cli.options, options);

  // Run tasks.
  exports.tasks(cli.tasks, cli.options);
};
<commit_msg>Adding done callback to grunt .cli method. Closes #36.<commit_after>/*
 * grunt
 * https://github.com/cowboy/grunt
 *
 * Copyright (c) 2012 "Cowboy" Ben Alman
 * Licensed under the MIT license.
 * http://benalman.com/about/license/
 */

var path = require('path');

// Perhaps, someday, this will be the only global.
global.grunt = {};

// Used to require grunt libs. Sweet, sugary goodness. Mmmmn.
grunt.require = function(libname) { return require(path.join(__dirname, 'grunt', libname)); };

// External libs, exposed globally for convenience.
global.async = require('async');
global.underscore = require('underscore');

// Internal grunt libs, exposed globally for convenience.
global.util = grunt.require('util');
global.task = grunt.require('task');
global.file = grunt.require('file');
global.fail = grunt.require('fail');
global.config = grunt.require('config');
global.option = grunt.require('option');
global.template = grunt.require('template');
global.log = grunt.require('log');
global.verbose = log.verbose;

grunt.version = file.readJson(path.join(__dirname, '../package.json')).version;
exports.version = grunt.version;

// Handle exceptions.
process.on('uncaughtException', function (e) {
  fail.warn(e, 3);
});

// Disable colors if --no-colors was passed.
function initColors() {
  var methods = Object.keys(String.prototype);
  // Requiring this here will modify String prototype everywhere.
  require('colors');

  // Disable colors.
  if (option('no-color')) {
    // Override "colors".
    Object.keys(String.prototype).filter(function(method) {
      // Filter out methods that existed before "colors" was required.
      return methods.indexOf(method) === -1;
    }).forEach(function(method) {
      // Replace each new method with a function that just returns `this`.
      String.prototype.__defineGetter__(method, function() { return this; });
    });

    // Override console.log (nodeunit, maybe others).
    console._log = console.log;
    console.log = function() {
      var args = util.toArray(arguments).map(function(value) {
        if (typeof value === 'string') {
          return value.replace(/\033\[[\d;]+m/g, '');
        }
        return value;
      });
      console._log.apply(console, args);
    };
  }
}

// Expose the task interface. I've never called this manually, and have no idea
// how it will work. But it might.
exports.tasks = function(tasks, options, done) {
  // Update options with passed-in options.
  option.init(options);

  // Init colors.
  initColors();

  if (option('help')) {
    // Load and display help if the user did --help.
    grunt.require('help');
  } else if (option('version')) {
    // Display the current grunt version if the user did --version.
    log.writeln('grunt v' + grunt.version);
    return;
  }

  // A little header stuff.
  verbose.header('Initializing').writeflags(option.flags(), 'Command-line options');

  // Determine and output which tasks will be run.
  var tasksSpecified = tasks && tasks.length > 0;
  tasks = task.parseArgs([tasksSpecified ? tasks : 'default']);

  // Initialize tasks.
  task.init(tasks);

  verbose.writeln();
  if (!tasksSpecified) {
    verbose.writeln('No tasks specified, running default tasks.');
  }
  verbose.writeflags(tasks, 'Running tasks');

  // Report, etc when all tasks have completed.
  task.options({
    error: function(e) {
      fail.warn(e, 3);
    },
    done: function() {
      // Output a final fail / success report.
      fail.report();

      if (done) {
        // Execute "done" function when done (only if passed, of course).
        done();
      } else {
        // Otherwise, explicitly exit.
        process.exit(0);
      }
    }
  });

  // Execute all tasks, in order. Passing each task individually in a forEach
  // allows the error callback to execute multiple times.
  tasks.forEach(function(name) { task.run(name); });
  task.start();
};

// This is only executed when run via command line.
exports.cli = function(options, done) {
  // Parse task list and options from the command line.
  var cli = grunt.require('cli');

  // CLI-parsed options override any passed-in "default" options.
  underscore.defaults(cli.options, options);

  // Run tasks.
  exports.tasks(cli.tasks, cli.options, done);
};
<|endoftext|>


<commit_before>var smash = require("smash"),
    d3 = require("d3"),
    jsdom = require("jsdom");

module.exports = function() {
  var files = [].slice.call(arguments).map(function(d) { return "src/" + d; }),
      expression = "mpld3",
      sandbox = {console: console, d3: d3};

  files.unshift("src/start");
  files.push("src/version");
  files.push("src/end");

  function topic() {
    var callback = this.callback;
    smash.load(files, expression, sandbox, function(error, result) {
      if (error) console.trace(error.stack);
      callback(error, result);
    });
  }

  topic.expression = function(_) {
    expression = _;
    return topic;
  };

  topic.sandbox = function(_) {
    sandbox = _;
    return topic;
  };

  topic.document = function(_) {
    var document = jsdom.jsdom("");

    sandbox = {
      d3 : d3,
      console: console,
      document: document,
      window: document.createWindow()
    };

    return topic;
  };

  return topic;
};

process.on("uncaughtException", function(e) {
  console.trace(e.stack);
});
<commit_msg>Replace document.createWindow with document.defaultView<commit_after>var smash = require("smash"),
    d3 = require("d3"),
    jsdom = require("jsdom");

module.exports = function() {
  var files = [].slice.call(arguments).map(function(d) { return "src/" + d; }),
      expression = "mpld3",
      sandbox = {console: console, d3: d3};

  files.unshift("src/start");
  files.push("src/version");
  files.push("src/end");

  function topic() {
    var callback = this.callback;
    smash.load(files, expression, sandbox, function(error, result) {
      if (error) console.trace(error.stack);
      callback(error, result);
    });
  }

  topic.expression = function(_) {
    expression = _;
    return topic;
  };

  topic.sandbox = function(_) {
    sandbox = _;
    return topic;
  };

  topic.document = function(_) {
    var document = jsdom.jsdom("");

    sandbox = {
      d3 : d3,
      console: console,
      document: document,
      window: document.defaultView
    };

    return topic;
  };

  return topic;
};

process.on("uncaughtException", function(e) {
  console.trace(e.stack);
});
<|endoftext|>


<commit_before>/*jshint bitwise: false*/
/*globals define*/
define([
  'box2d',
  'entities/physics-entity',
  'config/colors',
  'config/material',
  'config/settings',
  'utils'
], function( Box2D, PhysicsEntity, Colors, Material, Settings, Utils ) {
  'use strict';

  var PI2 = Utils.PI2;

  var Emotion = {
    NORMAL: 0,
    HIT: 1
  };

  function Player( x, y ) {
    PhysicsEntity.call( this, {
      shape: 'circle',
      radius: 3,
      fixture: {
        density: 0.25,
        friction: 0.5,
        restitution: 0.2,
        filter: {
          categoryBits: Material.MATTER
        }
      },
      body: {
        position: {
          x: x,
          y: y
        },
        linearDamping: 2,
        angularDamping: 0.1,
        type: 'dynamic'
      }
    });

    this.emotion = Emotion.NORMAL;
    this.emotionTimeout = null;
  }

  Player.Emotion = Emotion;

  Player.prototype = new PhysicsEntity();
  Player.prototype.constructor = Player;

  Player.prototype.draw = function( ctx ) {
    // 0.4 compensates for the difference between the drawn and fixture radii.
    // The drawn ring is at a radius of 0.35 with a maximum lineWidth of 0.18.
    // This results in a total relative width of (0.35 + 0.09) * 2 = 0.88.
    // 0.88 * 3 (physical radius) = 2.64 (draw radius).
    // Whereas:
    // 0.88 * (3 + 0.4) = 2.992, which gives some spacing.
    var radius = this.fixture.GetShape().GetRadius() + 0.4;

    var width  = 2 * radius,
        height = 2 * radius;

    ctx.save();
    ctx.translate( this.x, this.y );
    if ( this.angle ) {
      ctx.rotate( this.angle );
    }

    // Draw casing.
    ctx.lineWidth = 0.05 * width;

    // Top left.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, -Math.PI, -0.5 * Math.PI );
    ctx.strokeStyle = '#fef';
    ctx.stroke();

    // Top right.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, -0.5 * Math.PI, 0 );
    ctx.strokeStyle = '#cbe';
    ctx.stroke();

    // Bottom right.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, 0, 0.5 * Math.PI );
    ctx.strokeStyle = '#98b';
    ctx.stroke();

    // Bottom left.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, 0.5 * Math.PI, Math.PI );
    ctx.strokeStyle = '#658';
    ctx.stroke();

    // Draw main body.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.2 * width, 0, PI2 );
    ctx.fillStyle = '#ecf';
    ctx.fill();

    // Strokes.
    ctx.lineWidth = 0.02 * width;
    ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';
    ctx.stroke();

    ctx.beginPath();
    ctx.arc( 0, 0, 0.18 * width, 0, PI2 );
    ctx.strokeStyle = '#fff';
    ctx.stroke();

    if ( this.angle ) {
      ctx.save();
      ctx.rotate( -this.angle - this.game.camera.angle );
    }

    this.drawFace( ctx, width, height );

    if ( this.angle ) {
      ctx.restore();
    }

    this.drawRing( ctx, width );
  };

  Player.prototype.drawFace = function( ctx, width, height ) {
    var faceColor = Colors.Face;

    // Determine direction of movement.
    var dx = Utils.inverseLerp( Math.abs( this.vx ), 0, 20 ),
        dy = Utils.inverseLerp( Math.abs( this.vy ), 0, 20 );

    dx = Utils.clamp( dx, 0, 1 );
    dy = Utils.clamp( dy, 0, 1 );

    dx *= this.vx < 0 ? -1 : 1;
    dy *= this.vy < 0 ? -1 : 1;

    dx *= 0.05 * width;
    dy *= 0.05 * width;

    dx += this.game.camera.x;
    dy += this.game.camera.y;

    var d = this.game.camera.toLocal( dx, dy );
    dx = d.x;
    dy = d.y;

    if ( this.emotion === Emotion.NORMAL ) {
      // Draw eyes.
      ctx.beginPath();

      ctx.save();
      ctx.scale( 0.6, 1 );

      // // Draw left eye.
      ctx.arc( -0.12 * width + dx, dy, 0.07 * width, 0, PI2 );
      // // Draw right eye.
      ctx.arc(  0.12 * width + dx, dy, 0.07 * width, 0, PI2 );

      ctx.fillStyle = faceColor;
      ctx.fill();
      ctx.restore();
    } else if ( this.emotion === Emotion.HIT ) {
      // Draw X.
      ctx.beginPath();

      // Left diagonal.
      ctx.moveTo( -0.08 * width + dx, -0.07 * height + dy );
      ctx.lineTo(  0.08 * width + dx,  0.07 * height + dy );
      // Right diagonal.
      ctx.moveTo( -0.08 * width + dx,  0.07 * height + dy );
      ctx.lineTo(  0.08 * width + dx, -0.07 * height + dy );

      ctx.lineWidth = 0.03 * width;
      ctx.strokeStyle = faceColor;
      ctx.stroke();
    }
  };

  Player.prototype.drawRing = function( ctx, width ) {
    if ( Settings.glow ) {
      ctx.globalCompositeOperation = 'lighter';
    }

    ctx.beginPath();
    ctx.arc( 0, 0, 0.35 * width, 0, PI2 );

    var glowColor = Colors.Glow[ Material.type( this.material ) ];

    if ( glowColor ) {
      ctx.lineWidth = ( 0.1 + Math.random() * 0.08 ) * width;
      ctx.strokeStyle = glowColor;
      ctx.stroke();
    }

    ctx.lineWidth = 0.07 * width;
    ctx.strokeStyle = '#fff';
    ctx.stroke();

    if ( Settings.glow ) {
      ctx.globalCompositeOperation = 'source-over';
    }

    ctx.restore();
  };

  Player.prototype.toggleMaterial = function() {
    this.material = this.material ^ ( Material.MATTER | Material.ANTIMATTER );
  };

  return Player;
});
<commit_msg>Smaller Player eye movements when hit.<commit_after>/*jshint bitwise: false*/
/*globals define*/
define([
  'box2d',
  'entities/physics-entity',
  'config/colors',
  'config/material',
  'config/settings',
  'utils'
], function( Box2D, PhysicsEntity, Colors, Material, Settings, Utils ) {
  'use strict';

  var PI2 = Utils.PI2;

  var Emotion = {
    NORMAL: 0,
    HIT: 1
  };

  function Player( x, y ) {
    PhysicsEntity.call( this, {
      shape: 'circle',
      radius: 3,
      fixture: {
        density: 0.25,
        friction: 0.5,
        restitution: 0.2,
        filter: {
          categoryBits: Material.MATTER
        }
      },
      body: {
        position: {
          x: x,
          y: y
        },
        linearDamping: 2,
        angularDamping: 0.1,
        type: 'dynamic'
      }
    });

    this.emotion = Emotion.NORMAL;
    this.emotionTimeout = null;
  }

  Player.Emotion = Emotion;

  Player.prototype = new PhysicsEntity();
  Player.prototype.constructor = Player;

  Player.prototype.draw = function( ctx ) {
    // 0.4 compensates for the difference between the drawn and fixture radii.
    // The drawn ring is at a radius of 0.35 with a maximum lineWidth of 0.18.
    // This results in a total relative width of (0.35 + 0.09) * 2 = 0.88.
    // 0.88 * 3 (physical radius) = 2.64 (draw radius).
    // Whereas:
    // 0.88 * (3 + 0.4) = 2.992, which gives some spacing.
    var radius = this.fixture.GetShape().GetRadius() + 0.4;

    var width  = 2 * radius,
        height = 2 * radius;

    ctx.save();
    ctx.translate( this.x, this.y );
    if ( this.angle ) {
      ctx.rotate( this.angle );
    }

    // Draw casing.
    ctx.lineWidth = 0.05 * width;

    // Top left.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, -Math.PI, -0.5 * Math.PI );
    ctx.strokeStyle = '#fef';
    ctx.stroke();

    // Top right.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, -0.5 * Math.PI, 0 );
    ctx.strokeStyle = '#cbe';
    ctx.stroke();

    // Bottom right.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, 0, 0.5 * Math.PI );
    ctx.strokeStyle = '#98b';
    ctx.stroke();

    // Bottom left.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.22 * width, 0.5 * Math.PI, Math.PI );
    ctx.strokeStyle = '#658';
    ctx.stroke();

    // Draw main body.
    ctx.beginPath();
    ctx.arc( 0, 0, 0.2 * width, 0, PI2 );
    ctx.fillStyle = '#ecf';
    ctx.fill();

    // Strokes.
    ctx.lineWidth = 0.02 * width;
    ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';
    ctx.stroke();

    ctx.beginPath();
    ctx.arc( 0, 0, 0.18 * width, 0, PI2 );
    ctx.strokeStyle = '#fff';
    ctx.stroke();

    if ( this.angle ) {
      ctx.save();
      ctx.rotate( -this.angle - this.game.camera.angle );
    }

    this.drawFace( ctx, width, height );

    if ( this.angle ) {
      ctx.restore();
    }

    this.drawRing( ctx, width );
  };

  Player.prototype.drawFace = function( ctx, width, height ) {
    var faceColor = Colors.Face;

    // Determine direction of movement.
    var dx = Utils.inverseLerp( Math.abs( this.vx ), 0, 20 ),
        dy = Utils.inverseLerp( Math.abs( this.vy ), 0, 20 );

    dx = Utils.clamp( dx, 0, 1 );
    dy = Utils.clamp( dy, 0, 1 );

    dx *= this.vx < 0 ? -1 : 1;
    dy *= this.vy < 0 ? -1 : 1;

    dx *= 0.05 * width;
    dy *= 0.05 * width;

    dx += this.game.camera.x;
    dy += this.game.camera.y;

    var d = this.game.camera.toLocal( dx, dy );
    dx = d.x;
    dy = d.y;

    if ( this.emotion === Emotion.NORMAL ) {
      // Draw eyes.
      ctx.beginPath();

      ctx.save();
      ctx.scale( 0.6, 1 );

      // // Draw left eye.
      ctx.arc( -0.12 * width + dx, dy, 0.07 * width, 0, PI2 );
      // // Draw right eye.
      ctx.arc(  0.12 * width + dx, dy, 0.07 * width, 0, PI2 );

      ctx.fillStyle = faceColor;
      ctx.fill();
      ctx.restore();
    } else if ( this.emotion === Emotion.HIT ) {
      // Draw X.
      ctx.beginPath();
      ctx.lineCap = 'round';

      // Smaller eye movements.
      dx *= 0.5;
      dy *= 0.5;

      // Left diagonal.
      ctx.moveTo( -0.08 * width + dx, -0.07 * height + dy );
      ctx.lineTo(  0.08 * width + dx,  0.07 * height + dy );
      // Right diagonal.
      ctx.moveTo( -0.08 * width + dx,  0.07 * height + dy );
      ctx.lineTo(  0.08 * width + dx, -0.07 * height + dy );

      ctx.lineWidth = 0.04 * width;
      ctx.strokeStyle = faceColor;
      ctx.stroke();

      ctx.lineCap = 'butt';
    }
  };

  Player.prototype.drawRing = function( ctx, width ) {
    if ( Settings.glow ) {
      ctx.globalCompositeOperation = 'lighter';
    }

    ctx.beginPath();
    ctx.arc( 0, 0, 0.35 * width, 0, PI2 );

    var glowColor = Colors.Glow[ Material.type( this.material ) ];

    if ( glowColor ) {
      ctx.lineWidth = ( 0.1 + Math.random() * 0.08 ) * width;
      ctx.strokeStyle = glowColor;
      ctx.stroke();
    }

    ctx.lineWidth = 0.07 * width;
    ctx.strokeStyle = '#fff';
    ctx.stroke();

    if ( Settings.glow ) {
      ctx.globalCompositeOperation = 'source-over';
    }

    ctx.restore();
  };

  Player.prototype.toggleMaterial = function() {
    this.material = this.material ^ ( Material.MATTER | Material.ANTIMATTER );
  };

  return Player;
});
<|endoftext|>


<commit_before>var Q = require('q');
var _ = require('lodash');
var request = require('request');

var logger = require("./utils/logger")("hooks");

var HOOKS = {};
var POSTHOOKS = {
    'users.auth': function(data) {
        // Valid data
        if (!_.has(data, "id") || !_.has(data, "name")
        || !_.has(data, "token") || !_.has(data, "email")) {
            throw "Invalid authentication data";
        }

        return data;
    }
};
var SECRET_TOKEN = null;

// Call hook
var use = function(hook, data) {
    logger.log("call hook ", hook);

    if (!HOOKS[hook]) return Q.reject("Hook '"+hook+"' doesn't exists");

    return Q()
    .then(function() {
        var handler = HOOKS[hook];

        if (_.isFunction(handler)) {
            return Q(handler(data));
        } else if (_.isString(handler)) {
            var d = Q.defer();

            // Do http requests
            request.post(handler, {
                'body': {
                    'data': data,
                    'hook': hook
                },
                'headers': {
                    'Authorization': SECRET_TOKEN
                },
                'json': true,
            }, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    d.resolve(body);
                } else {
                    d.reject(new Error("Error with "+hook+" webhook: "+(body ? (body.error || body) : error.message)));
                }
            });

            return d.promise;
        } else {
            throw "Not a valid hook";
        }
    })
    .then(function(data) {
        if (POSTHOOKS[hook]) {
            return POSTHOOKS[hook](data);
        }
        return data;
    })
    .fail(function(err) {
        logger.error("Error with hook:");
        logger.exception(err, false);

        return Q.reject(err);
    });
};

// Init hook system
var init = function(options) {
    logger.log("init hooks");

    HOOKS = options.hooks;
    SECRET_TOKEN = options.secret;
};

module.exports = {
    init: init,
    use: use
};

<commit_msg>Send boxid to webhook<commit_after>var Q = require('q');
var _ = require('lodash');
var request = require('request');

var logger = require("./utils/logger")("hooks");

var BOXID = null;
var HOOKS = {};
var POSTHOOKS = {
    'users.auth': function(data) {
        // Valid data
        if (!_.has(data, "id") || !_.has(data, "name")
        || !_.has(data, "token") || !_.has(data, "email")) {
            throw "Invalid authentication data";
        }

        return data;
    }
};
var SECRET_TOKEN = null;

// Call hook
var use = function(hook, data) {
    logger.log("call hook ", hook);

    if (!HOOKS[hook]) return Q.reject("Hook '"+hook+"' doesn't exists");

    return Q()
    .then(function() {
        var handler = HOOKS[hook];

        if (_.isFunction(handler)) {
            return Q(handler(data));
        } else if (_.isString(handler)) {
            var d = Q.defer();

            // Do http requests
            request.post(handler, {
                'body': {
                    'id': BOXID,
                    'data': data,
                    'hook': hook
                },
                'headers': {
                    'Authorization': SECRET_TOKEN
                },
                'json': true,
            }, function (error, response, body) {
                if (!error && response.statusCode == 200) {
                    d.resolve(body);
                } else {
                    d.reject(new Error("Error with "+hook+" webhook: "+(body ? (body.error || body) : error.message)));
                }
            });

            return d.promise;
        } else {
            throw "Not a valid hook";
        }
    })
    .then(function(data) {
        if (POSTHOOKS[hook]) {
            return POSTHOOKS[hook](data);
        }
        return data;
    })
    .fail(function(err) {
        logger.error("Error with hook:");
        logger.exception(err, false);

        return Q.reject(err);
    });
};

// Init hook system
var init = function(options) {
    logger.log("init hooks");

    BOXID = options.id;
    HOOKS = options.hooks;
    SECRET_TOKEN = options.secret;
};

module.exports = {
    init: init,
    use: use
};

<|endoftext|>


<commit_before>// Test File
var db = require('../tmp/db.js');
var assert = require('assert');

var post = {
    title: 'LRC Network',
    content: 'Hello, World!',
    postCreated : new Date(),
    postPublished: '',
    lastUpdated: '22-07-2015',
    status: 'draft',
    // should be author id: string
    author: 'Maheso Anabrang',
    tags: ['hello', 'dummy']
};

var post_id;

describe('Blogel Database Test', function(){

    it('Should save new post', function(done){
       db.savePost(post).then(function(status){
           //console.log(status);
	   post_id = status.generated_keys[0];
	   done();
       }, function(err){
           done(err);
       });
    })

    it('Should get post data base on id', function(done){
       db.getPostById(post_id).then(function(data){
	  //console.log('Get Post:');
          //console.log(data);
          assert.equal(data.title,post.title, 'post title should be '+post.title);
	  done();
       }, function(err){
          done(err);
       });
    });

    it('Should delete post with specified id', function(done){
       db.deletePost(post_id).then(function(result){
           //console.log(result);
	   assert.equal(1, result.deleted, 'deleted should be 1');
	   done();
       }, function(err){
           done(err);
       })
    })
})
<commit_msg>Add test for post update function<commit_after>// Test File
var db = require('../tmp/db.js');
var assert = require('assert');

var post = {
    title: 'LRC Network',
    content: 'Hello, World!',
    postCreated : new Date(),
    postPublished: '',
    lastUpdated: '22-07-2015',
    status: 'draft',
    // should be author id: string
    author: 'Maheso Anabrang',
    tags: ['hello', 'dummy']
};

var post_update = {
    title: 'LRC Network',
    content: 'Inductor, Resisto & Capacitor Network',
    //postCreated : new Date(),
    postPublished: new Date(),
    lastUpdated: '22-07-2015',
    status: 'published',
    // should be author id: string
    author: 'Maheso Anabrang',
    tags: ['hello', 'dummy', 'electronic']
}

var post_id;

describe('Blogel Database Test', function(){

    it('Should save new post', function(done){
       db.savePost(post).then(function(status){
           //console.log(status);
	   post_id = status.generated_keys[0];
	   done();
       }, function(err){
           done(err);
       });
    })

    it('Should get post data base on id', function(done){
       db.getPostById(post_id).then(function(data){
	  //console.log('Get Post:');
          //console.log(data);
          assert.equal(data.title,post.title, 'post title should be '+post.title);
	  done();
       }, function(err){
          done(err);
       });
    });

    it('Should update post', function(){

       post_update.generated_keys = [post_id];

       db.updatePost(post_update).then(function(data){
           //console.log(data);
           assert.equal(1, data.replaced, 'replaced (updated) should be 1');
	   done();
       }, function(err){
           done(err);
       });
    })

    it('Should delete post with specified id', function(done){
       db.deletePost(post_id).then(function(result){
           //console.log(result);
	   assert.equal(1, result.deleted, 'deleted should be 1');
	   done();
       }, function(err){
           done(err);
       })
    })
})
<|endoftext|>


<commit_before>"use strict";

/*global module, require*/

var _ = require("lodash"),
    charsPerW = 0.13,
    linesPerH = 0.063,
    heightOffset = 15,
    lineBreak = /[\r\n]+/,
    wordBreak = /[ \t]+/;

var clamp = function(num) {
    return Math.max(
	parseInt(num),
	1
    );
};

// TODO double line separator
module.exports = function(textElement, getText, getWidth, getHeight) {
    var w = getWidth(textElement.datum()),
	h = getHeight(textElement.datum()),

	charsPerSpan = clamp(charsPerW * w),
	maxLines = clamp(linesPerH * h);

    var tspans = textElement.selectAll("tspan")
	    .data(
		function(d, i) {
		    var text = getText(d, i),
			lines = text.split(lineBreak),
			spans = [],
			overflow = false;

		    lines.forEach(function(line) {
			var words = line.split(wordBreak),
			    current,
			    currentLength;

			if (overflow || spans.length >= maxLines) {
			    overflow = true;
			    return;
			}

			for (var i = 0, len = words.length; i < len; i++) {
			    var word = words[i],
				wordLength = word.length;

			    if (wordLength > charsPerSpan) {
				// Truncate words which are too wide to fit.
				word = word.substring(0, charsPerSpan - 2) + "..";
				wordLength = charsPerSpan;
			    }

			    if (!current) {
				current = word;
				currentLength = wordLength;

			    } else if (currentLength + wordLength < charsPerSpan) {
				current += " " + word;
				currentLength += 1 + wordLength;

			    } else {
				spans.push(current);

				if (spans.length >= maxLines) {
				    overflow = true;
				    break;
   				}

				current = word;
				currentLength = wordLength;
			    }
			}

			if (!overflow && current && current.length > 0) {
			    spans.push(current);
			}
		    });

		    if (overflow) {
			var last = spans[spans.length - 1];
			spans[spans.length - 1] = last.substring(0, charsPerSpan - 2) + "..";
		    }

		    return spans;
		},
		function(span) {
		    return span;
		});

    tspans.exit().remove();

    tspans.enter()
	.append("tspan")
	.attr("width", w);

    tspans
    	.attr("x", function(d, i) {
	    return 0;
	})
	.attr("y", function(d, i) {
	    return 15 + (i * heightOffset);
	})
	.text(function(d, i) {
	    return d;
	});
};
<commit_msg>SVG text wrapping now correctly determines the width and height of the text on a per-element basis. Previously it was using the same width and height for every element in a selection.<commit_after>"use strict";

/*global module, require*/

var _ = require("lodash"),
    charsPerW = 0.13,
    linesPerH = 0.063,
    heightOffset = 15,
    lineBreak = /[\r\n]+/,
    wordBreak = /[ \t]+/;

var clamp = function(num) {
    return Math.max(
	parseInt(num),
	1
    );
};

// TODO double line separator
module.exports = function(textElement, getText, getWidth, getHeight) {
    var tspans = textElement.selectAll("tspan")
	    .data(
		function(d, i) {
		    var w = getWidth(d),
			h = getHeight(d),
			charsPerSpan = clamp(charsPerW * w),
			maxLines = clamp(linesPerH * h),

			text = getText(d, i),
			lines = text.split(lineBreak),
			spans = [],
			overflow = false;

		    lines.forEach(function(line) {
			var words = line.split(wordBreak),
			    current,
			    currentLength;

			if (overflow || spans.length >= maxLines) {
			    overflow = true;
			    return;
			}

			for (var i = 0, len = words.length; i < len; i++) {
			    var word = words[i],
				wordLength = word.length;

			    if (wordLength > charsPerSpan) {
				// Truncate words which are too wide to fit.
				word = word.substring(0, charsPerSpan - 2) + "..";
				wordLength = charsPerSpan;
			    }

			    if (!current) {
				current = word;
				currentLength = wordLength;

			    } else if (currentLength + wordLength < charsPerSpan) {
				current += " " + word;
				currentLength += 1 + wordLength;

			    } else {
				spans.push(current);

				if (spans.length >= maxLines) {
				    overflow = true;
				    break;
   				}

				current = word;
				currentLength = wordLength;
			    }
			}

			if (!overflow && current && current.length > 0) {
			    spans.push(current);
			}
		    });

		    if (overflow) {
			var last = spans[spans.length - 1];
			spans[spans.length - 1] = last.substring(0, charsPerSpan - 2) + "..";
		    }

		    return spans;
		});

    tspans.exit().remove();

    tspans.enter()
	.append("tspan");

    tspans
    	.attr("x", function(d, i) {
	    return 0;
	})
	.attr("y", function(d, i) {
	    return 15 + (i * heightOffset);
	})
	.text(function(d, i) {
	    return d;
	});
};
<|endoftext|>