'use strict';

var should = require('should'),
  request = require('supertest'),
  path = require('path'),
  mongoose = require('mongoose'),
  User = mongoose.model('User'),
  featureMapper = mongoose.model('featureMapper'),
  express = require(path.resolve('./config/lib/express'));

/**
 * Globals
 */
var app, agent, credentials, user, featureMapper;

/**
 * featureMapper routes tests
 */
describe('featureMapper CRUD tests', function () {

  before(function (done) {
    // Get application
    app = express.init(mongoose);
    agent = request.agent(app);

    done();
  });

  beforeEach(function (done) {
    // Create user credentials
    credentials = {
      username: 'username',
      password: 'M3@n.jsI$Aw3$0m3'
    };

    // Create a new user
    user = new User({
      firstName: 'Full',
      lastName: 'Name',
      displayName: 'Full Name',
      email: 'test@test.com',
      username: credentials.username,
      password: credentials.password,
      provider: 'local'
    });

    // Save a user to the test db and create new featureMapper
    user.save(function () {
      featureMapper = {
        title: 'featureMapper Title',
        content: 'featureMapper Content'
      };

      done();
    });
  });

  it('should be able to save an featureMapper if logged in', function (done) {
    agent.post('/api/auth/signin')
      .send(credentials)
      .expect(200)
      .end(function (signinErr, signinRes) {
        // Handle signin error
        if (signinErr) {
          return done(signinErr);
        }

        // Get the userId
        var userId = user.id;

        // Save a new featureMapper
        agent.post('/api/featureMappers')
          .send(featureMapper)
          .expect(200)
          .end(function (featureMapperSaveErr, featureMapperSaveRes) {
            // Handle featureMapper save error
            if (featureMapperSaveErr) {
              return done(featureMapperSaveErr);
            }

            // Get a list of featureMappers
            agent.get('/api/featureMappers')
              .end(function (featureMappersGetErr, featureMappersGetRes) {
                // Handle featureMapper save error
                if (featureMappersGetErr) {
                  return done(featureMappersGetErr);
                }

                // Get featureMappers list
                var featureMappers = featureMappersGetRes.body;

                // Set assertions
                (featureMappers[0].user._id).should.equal(userId);
                (featureMappers[0].title).should.match('featureMapper Title');

                // Call the assertion callback
                done();
              });
          });
      });
  });

  it('should not be able to save an featureMapper if not logged in', function (done) {
    agent.post('/api/featureMappers')
      .send(featureMapper)
      .expect(403)
      .end(function (featureMapperSaveErr, featureMapperSaveRes) {
        // Call the assertion callback
        done(featureMapperSaveErr);
      });
  });

  it('should not be able to save an featureMapper if no title is provided', function (done) {
    // Invalidate title field
    featureMapper.title = '';

    agent.post('/api/auth/signin')
      .send(credentials)
      .expect(200)
      .end(function (signinErr, signinRes) {
        // Handle signin error
        if (signinErr) {
          return done(signinErr);
        }

        // Get the userId
        var userId = user.id;

        // Save a new featureMapper
        agent.post('/api/featureMappers')
          .send(featureMapper)
          .expect(400)
          .end(function (featureMapperSaveErr, featureMapperSaveRes) {
            // Set message assertion
            (featureMapperSaveRes.body.message).should.match('Title cannot be blank');

            // Handle featureMapper save error
            done(featureMapperSaveErr);
          });
      });
  });

  it('should be able to update an featureMapper if signed in', function (done) {
    agent.post('/api/auth/signin')
      .send(credentials)
      .expect(200)
      .end(function (signinErr, signinRes) {
        // Handle signin error
        if (signinErr) {
          return done(signinErr);
        }

        // Get the userId
        var userId = user.id;

        // Save a new featureMapper
        agent.post('/api/featureMappers')
          .send(featureMapper)
          .expect(200)
          .end(function (featureMapperSaveErr, featureMapperSaveRes) {
            // Handle featureMapper save error
            if (featureMapperSaveErr) {
              return done(featureMapperSaveErr);
            }

            // Update featureMapper title
            featureMapper.title = 'WHY YOU GOTTA BE SO MEAN?';

            // Update an existing featureMapper
            agent.put('/api/featureMappers/' + featureMapperSaveRes.body._id)
              .send(featureMapper)
              .expect(200)
              .end(function (featureMapperUpdateErr, featureMapperUpdateRes) {
                // Handle featureMapper update error
                if (featureMapperUpdateErr) {
                  return done(featureMapperUpdateErr);
                }

                // Set assertions
                (featureMapperUpdateRes.body._id).should.equal(featureMapperSaveRes.body._id);
                (featureMapperUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?');

                // Call the assertion callback
                done();
              });
          });
      });
  });

  it('should be able to get a list of featureMappers if not signed in', function (done) {
    // Create new featureMapper model instance
    var featureMapperObj = new featureMapper(featureMapper);

    // Save the featureMapper
    featureMapperObj.save(function () {
      // Request featureMappers
      request(app).get('/api/featureMappers')
        .end(function (req, res) {
          // Set assertion
          res.body.should.be.instanceof(Array).and.have.lengthOf(1);

          // Call the assertion callback
          done();
        });

    });
  });

  it('should be able to get a single featureMapper if not signed in', function (done) {
    // Create new featureMapper model instance
    var featureMapperObj = new featureMapper(featureMapper);

    // Save the featureMapper
    featureMapperObj.save(function () {
      request(app).get('/api/featureMappers/' + featureMapperObj._id)
        .end(function (req, res) {
          // Set assertion
          res.body.should.be.instanceof(Object).and.have.property('title', featureMapper.title);

          // Call the assertion callback
          done();
        });
    });
  });

  it('should return proper error for single featureMapper with an invalid Id, if not signed in', function (done) {
    // test is not a valid mongoose Id
    request(app).get('/api/featureMappers/test')
      .end(function (req, res) {
        // Set assertion
        res.body.should.be.instanceof(Object).and.have.property('message', 'featureMapper is invalid');

        // Call the assertion callback
        done();
      });
  });

  it('should return proper error for single featureMapper which doesnt exist, if not signed in', function (done) {
    // This is a valid mongoose Id but a non-existent featureMapper
    request(app).get('/api/featureMappers/559e9cd815f80b4c256a8f41')
      .end(function (req, res) {
        // Set assertion
        res.body.should.be.instanceof(Object).and.have.property('message', 'No featureMapper with that identifier has been found');

        // Call the assertion callback
        done();
      });
  });

  it('should be able to delete an featureMapper if signed in', function (done) {
    agent.post('/api/auth/signin')
      .send(credentials)
      .expect(200)
      .end(function (signinErr, signinRes) {
        // Handle signin error
        if (signinErr) {
          return done(signinErr);
        }

        // Get the userId
        var userId = user.id;

        // Save a new featureMapper
        agent.post('/api/featureMappers')
          .send(featureMapper)
          .expect(200)
          .end(function (featureMapperSaveErr, featureMapperSaveRes) {
            // Handle featureMapper save error
            if (featureMapperSaveErr) {
              return done(featureMapperSaveErr);
            }

            // Delete an existing featureMapper
            agent.delete('/api/featureMappers/' + featureMapperSaveRes.body._id)
              .send(featureMapper)
              .expect(200)
              .end(function (featureMapperDeleteErr, featureMapperDeleteRes) {
                // Handle featureMapper error error
                if (featureMapperDeleteErr) {
                  return done(featureMapperDeleteErr);
                }

                // Set assertions
                (featureMapperDeleteRes.body._id).should.equal(featureMapperSaveRes.body._id);

                // Call the assertion callback
                done();
              });
          });
      });
  });

  it('should not be able to delete an featureMapper if not signed in', function (done) {
    // Set featureMapper user
    featureMapper.user = user;

    // Create new featureMapper model instance
    var featureMapperObj = new featureMapper(featureMapper);

    // Save the featureMapper
    featureMapperObj.save(function () {
      // Try deleting featureMapper
      request(app).delete('/api/featureMappers/' + featureMapperObj._id)
        .expect(403)
        .end(function (featureMapperDeleteErr, featureMapperDeleteRes) {
          // Set message assertion
          (featureMapperDeleteRes.body.message).should.match('User is not authorized');

          // Handle featureMapper error error
          done(featureMapperDeleteErr);
        });

    });
  });

  afterEach(function (done) {
    User.remove().exec(function () {
      featureMapper.remove().exec(done);
    });
  });
});
