'use strict';

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _fs = require('fs');

var _fs2 = _interopRequireDefault(_fs);

var _lodash = require('lodash');

var _lodash2 = _interopRequireDefault(_lodash);

var _bluebird = require('bluebird');

var _bluebird2 = _interopRequireDefault(_bluebird);

var _yeomanTest = require('yeoman-test');

var _yeomanTest2 = _interopRequireDefault(_yeomanTest);

var _yeomanAssert = require('yeoman-assert');

var _yeomanAssert2 = _interopRequireDefault(_yeomanAssert);

var _getExpectedFiles = require('./get-expected-files');

var getExpectedFiles = _interopRequireWildcard(_getExpectedFiles);

var _testHelpers = require('./test-helpers');

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var defaultOptions = {
  buildtool: 'grunt',
  transpiler: 'babel',
  markup: 'html',
  stylesheet: 'sass',
  router: 'uirouter',
  testing: 'mocha',
  chai: 'expect',
  bootstrap: true,
  uibootstrap: true,
  odms: ['mongoose'],
  auth: true,
  oauth: [],
  socketio: true
};
var TEST_DIR = __dirname;

function runEndpointGen(name) {
  var opt = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

  var prompts = opt.prompts || {};
  var options = opt.options || {};
  var config = opt.config;

  return new _bluebird2.default(function (resolve, reject) {
    var gen = _yeomanTest2.default.run(require.resolve('../generators/endpoint'), { tmpdir: false }).withOptions(options).withArguments([name]).withPrompts(prompts);

    if (config) {
      gen.withLocalConfig(config);
    }

    gen.on('error', reject).on('end', function () {
      return resolve();
    });
  });
}

describe('angular-fullstack:app', function () {
  describe('default settings', function () {
    var dir;

    beforeEach(function () {
      return (0, _testHelpers.runGen)(defaultOptions).then(function (_dir) {
        dir = _dir;
      });
    });

    it('generates the proper files', function () {
      var expectedFiles = getExpectedFiles.app(defaultOptions);
      _yeomanAssert2.default.file(expectedFiles);
      return (0, _testHelpers.assertOnlyFiles)(expectedFiles, _path2.default.normalize(dir)).should.be.fulfilled();
    });

    it('passes JSCS', function () {
      return (0, _testHelpers.runCmd)('grunt jscs').should.be.fulfilled();
    });

    it('passes JSHint', function () {
      return (0, _testHelpers.runCmd)('grunt jshint').should.be.fulfilled();
    });

    it('passes client tests', function () {
      return (0, _testHelpers.runCmd)('grunt test:client').should.be.fulfilled();
    });

    it('passes server tests', function () {
      return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
    });

    describe('with a generated endpoint', function () {
      beforeEach(function () {
        return (0, _testHelpers.readJSON)(_path2.default.join(dir, '.yo-rc.json')).then(function (config) {
          return runEndpointGen('foo', { config: config['generator-angular-fullstack'] });
        });
      });

      it('should run server tests successfully', function () {
        return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
      });
    });

    describe('with a generated capitalized endpoint', function () {
      beforeEach(function () {
        return (0, _testHelpers.readJSON)(_path2.default.join(dir, '.yo-rc.json')).then(function (config) {
          return runEndpointGen('Foo', { config: config['generator-angular-fullstack'] });
        });
      });

      it('should run server tests successfully', function () {
        return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
      });
    });

    describe('with a generated path name endpoint', function () {
      beforeEach(function () {
        return (0, _testHelpers.readJSON)(_path2.default.join(dir, '.yo-rc.json')).then(function (config) {
          return runEndpointGen('foo/bar', { config: config['generator-angular-fullstack'] });
        });
      });

      it('should run server tests successfully', function () {
        return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
      });
    });

    describe('with a generated snake-case endpoint', function () {
      beforeEach(function () {
        return (0, _testHelpers.readJSON)(_path2.default.join(dir, '.yo-rc.json')).then(function (config) {
          return runEndpointGen('foo-bar', { config: config['generator-angular-fullstack'] });
        });
      });

      it('should run server tests successfully', function () {
        return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
      });
    });

    if (!process.env.SKIP_E2E) {
      it('should run e2e tests successfully', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e').should.be.fulfilled();
      });

      it('should run e2e tests successfully for production app', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e:prod').should.be.fulfilled();
      });
    }
  });

  describe('default settings using existing `.yo-rc.json`', function () {
    var dir;
    var jscsResult;
    var lintResult;
    var clientTestResult;
    var serverTestResult;

    before(function () {
      return (0, _testHelpers.runGen)(null, {
        copyConfigFile: true,
        options: {
          skipInstall: true,
          skipConfig: true
        }
      }).then(function (_dir) {
        dir = _dir;
        jscsResult = (0, _testHelpers.runCmd)('grunt jscs');
        lintResult = (0, _testHelpers.runCmd)('grunt jshint');
        clientTestResult = (0, _testHelpers.runCmd)('grunt test:client');
        serverTestResult = (0, _testHelpers.runCmd)('grunt test:server');
      });
    });

    it('generates the proper files', function () {
      var expectedFiles = getExpectedFiles.app(defaultOptions);
      _yeomanAssert2.default.file(expectedFiles);
      return (0, _testHelpers.assertOnlyFiles)(expectedFiles, _path2.default.normalize(dir)).should.be.fulfilled();
    });

    it('passes JSCS', function () {
      return jscsResult.should.be.fulfilled();
    });

    it('passes JSHint', function () {
      return lintResult.should.be.fulfilled();
    });

    it('passes client tests', function () {
      return clientTestResult.should.be.fulfilled();
    });

    it('passes server tests', function () {
      return serverTestResult.should.be.fulfilled();
    });
  });

  describe('with TypeScript, Jade, Jasmine, LESS, & OAuth', function () {
    var dir;
    var jscsResult;
    var lintResult;
    var clientTestResult;
    var serverTestResult;
    var testOptions = {
      buildtool: 'grunt',
      transpiler: 'ts',
      markup: 'jade',
      stylesheet: 'less',
      router: 'uirouter',
      testing: 'jasmine',
      odms: ['mongoose'],
      auth: true,
      oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'],
      socketio: true,
      bootstrap: true,
      uibootstrap: true
    };

    before(function () {
      return (0, _testHelpers.runGen)(testOptions).then(function (_dir) {
        dir = _dir;
        jscsResult = (0, _testHelpers.runCmd)('grunt jscs');
        lintResult = (0, _testHelpers.runCmd)('grunt tslint');
        clientTestResult = (0, _testHelpers.runCmd)('grunt test:client');
        serverTestResult = (0, _testHelpers.runCmd)('grunt test:server');
      });
    });

    it('should generate the proper files', function () {
      var expectedFiles = getExpectedFiles.app(testOptions);
      _yeomanAssert2.default.file(expectedFiles);
      return (0, _testHelpers.assertOnlyFiles)(expectedFiles, _path2.default.normalize(dir)).should.be.fulfilled();
    });

    it('passes JSCS', function () {
      return jscsResult.should.be.fulfilled();
    });

    it('passes lint', function () {
      return lintResult.should.be.fulfilled();
    });

    it('should run client tests successfully', function () {
      return clientTestResult.should.be.fulfilled();
    });

    it('should run server tests successfully', function () {
      return serverTestResult.should.be.fulfilled();
    });

    describe('with a generated endpoint', function () {
      beforeEach(function () {
        return (0, _testHelpers.readJSON)(_path2.default.join(dir, '.yo-rc.json')).then(function (config) {
          return runEndpointGen('foo', { config: config['generator-angular-fullstack'] });
        });
      });

      it('should run server tests successfully', function () {
        return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
      });
    });

    if (!process.env.SKIP_E2E) {
      it('should run e2e tests successfully', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e').should.be.fulfilled();
      });

      it('should run e2e tests successfully for production app', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e:prod').should.be.fulfilled();
      });
    }
  });

  describe('with sequelize models, auth', function () {
    var dir;
    var jscsResult;
    var lintResult;
    var clientTestResult;
    var serverTestResult;
    var testOptions = {
      buildtool: 'grunt',
      transpiler: 'babel',
      markup: 'jade',
      stylesheet: 'css',
      router: 'uirouter',
      testing: 'jasmine',
      odms: ['sequelize'],
      auth: true,
      oauth: ['twitterAuth', 'facebookAuth', 'googleAuth'],
      socketio: true,
      bootstrap: true,
      uibootstrap: true
    };
    this.retries(3); // Sequelize seems to be quite flaky

    beforeEach(function () {
      return (0, _testHelpers.runGen)(testOptions).then(function (_dir) {
        dir = _dir;
        jscsResult = (0, _testHelpers.runCmd)('grunt jscs');
        lintResult = (0, _testHelpers.runCmd)('grunt jshint');
        clientTestResult = (0, _testHelpers.runCmd)('grunt test:client');
        serverTestResult = (0, _testHelpers.runCmd)('grunt test:server');
      });
    });

    it('should generate the proper files', function () {
      var expectedFiles = getExpectedFiles.app(testOptions);
      _yeomanAssert2.default.file(expectedFiles);
      return (0, _testHelpers.assertOnlyFiles)(expectedFiles, _path2.default.normalize(dir)).should.be.fulfilled();
    });

    it('passes JSCS', function () {
      return jscsResult.should.be.fulfilled();
    });

    it('passes lint', function () {
      return lintResult.should.be.fulfilled();
    });

    it('should run client tests successfully', function () {
      return clientTestResult.should.be.fulfilled();
    });

    it('should run server tests successfully', function () {
      return serverTestResult.should.be.fulfilled();
    });

    describe('with a generated endpoint', function () {
      beforeEach(function () {
        return (0, _testHelpers.readJSON)(_path2.default.join(dir, '.yo-rc.json')).then(function (config) {
          return runEndpointGen('foo', { config: config['generator-angular-fullstack'] });
        });
      });

      it('should run server tests successfully', function () {
        return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
      });
    });

    if (!process.env.SKIP_E2E) {
      it('should run e2e tests successfully', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e').should.be.fulfilled();
      });

      it('should run e2e tests successfully for production app', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e:prod').should.be.fulfilled();
      });
    }
  });

  describe('with TypeScript, Mocha + Chai (should) and no server options', function () {
    var dir;
    var jscsResult;
    var lintResult;
    var clientTestResult;
    var serverTestResult;
    var testOptions = {
      buildtool: 'grunt',
      transpiler: 'ts',
      markup: 'jade',
      stylesheet: 'stylus',
      router: 'uirouter',
      testing: 'mocha',
      chai: 'should',
      odms: [],
      auth: false,
      oauth: [],
      socketio: false,
      bootstrap: false,
      uibootstrap: false
    };

    beforeEach(function () {
      return (0, _testHelpers.runGen)(testOptions).then(function (_dir) {
        dir = _dir;
        jscsResult = (0, _testHelpers.runCmd)('grunt jscs');
        lintResult = (0, _testHelpers.runCmd)('grunt tslint');
        clientTestResult = (0, _testHelpers.runCmd)('grunt test:client');
        serverTestResult = (0, _testHelpers.runCmd)('grunt test:server');
      });
    });

    it('should generate the proper files', function () {
      var expectedFiles = getExpectedFiles.app(testOptions);
      _yeomanAssert2.default.file(expectedFiles);
      return (0, _testHelpers.assertOnlyFiles)(expectedFiles, _path2.default.normalize(dir)).should.be.fulfilled();
    });

    it('passes JSCS', function () {
      return jscsResult.should.be.fulfilled();
    });

    it('passes lint', function () {
      return lintResult.should.be.fulfilled();
    });

    it('should run client tests successfully', function () {
      return clientTestResult.should.be.fulfilled();
    });

    it('should run server tests successfully', function () {
      return serverTestResult.should.be.fulfilled();
    });

    describe('with a generated endpoint', function () {
      beforeEach(function () {
        return (0, _testHelpers.readJSON)(_path2.default.join(dir, '.yo-rc.json')).then(function (config) {
          return runEndpointGen('foo', { config: config['generator-angular-fullstack'] });
        });
      });

      it('should run server tests successfully', function () {
        return (0, _testHelpers.runCmd)('grunt test:server').should.be.fulfilled();
      });
    });

    if (!process.env.SKIP_E2E) {
      it('should run e2e tests successfully', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e').should.be.fulfilled();
      });

      it('should run e2e tests successfully for production app', function () {
        this.retries(2);
        return (0, _testHelpers.runCmd)('grunt test:e2e:prod').should.be.fulfilled();
      });
    }
  });
});