text: 'use strict';
  const AuthPlugin = require('../../../server/auth');
  const AuthenticatedUser = require('../fixtures/credentials-admin');
  const Code = require('code');
  const Config = require('../../../config');
  const Hapi = require('hapi');
  const HapiAuth = require('hapi-auth-cookie');
  const Lab = require('lab');
  const MakeMockModel = require('../fixtures/make-mock-model');
  const Manifest = require('../../../manifest');
  const Path = require('path');
  const Proxyquire = require('proxyquire');
  const SitesPlugin = require('../../../server/api/sites');
  
  
  const lab = exports.lab = Lab.script();
  let request;
  let server;
  let stub;
  
  
  lab.before((done) => {
  
      stub = {
          Site: MakeMockModel()
      };
  
      const proxy = {};
      proxy[Path.join(process.cwd(), './server/models/site')] = stub.Site;
  
      const ModelsPlugin = {
          register: Proxyquire('hapi-mongo-models', proxy),
          options: Manifest.get('/registrations').filter((reg) => {
  
              if (reg.plugin &&
                  reg.plugin.register &&
                  reg.plugin.register === 'hapi-mongo-models') {
  
                  return true;
              }
  
              return false;
          })[0].plugin.options
      };
  
      const plugins = [HapiAuth, ModelsPlugin, AuthPlugin, SitesPlugin];
      server = new Hapi.Server();
      server.connection({ port: Config.get('/port/web') });
      server.register(plugins, (err) => {
  
          if (err) {
              return done(err);
          }
  
          server.initialize(done);
      });
  });
  
  
  lab.after((done) => {
  
      server.plugins['hapi-mongo-models'].MongoModels.disconnect();
      done();
  });
  
  
  lab.experiment('Sites Plugin Result List', () => {
  
      lab.beforeEach((done) => {
  
          request = {
              method: 'GET',
              url: '/sites',
              credentials: AuthenticatedUser
          };
  
          done();
      });
  
  
      lab.test('it returns an error when paged find fails', (done) => {
  
          stub.Site.pagedFind = function () {
  
              const args = Array.prototype.slice.call(arguments);
              const callback = args.pop();
  
              callback(Error('paged find failed'));
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(500);
              done();
          });
      });
  
  
      lab.test('it returns an array of documents successfully', (done) => {
  
          stub.Site.pagedFind = function () {
  
              const args = Array.prototype.slice.call(arguments);
              const callback = args.pop();
  
              callback(null, { data: [{}, {}, {}] });
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(200);
              Code.expect(response.result.data).to.be.an.array();
              Code.expect(response.result.data[0]).to.be.an.object();
  
              done();
          });
      });
  
  
      lab.test('it returns an array of documents successfully (using filters)', (done) => {
  
          stub.Site.pagedFind = function () {
  
              const args = Array.prototype.slice.call(arguments);
              const callback = args.pop();
  
              callback(null, { data: [{}, {}, {}] });
          };
  
          request.url += '?name=testsite';
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(200);
              Code.expect(response.result.data).to.be.an.array();
              Code.expect(response.result.data[0]).to.be.an.object();
  
              done();
          });
      });
  
      // lab.test('it returns only documents from current user'), (done) => {});
  
      // lab.test('it returns all documents from an admin user'), (done) => {});
  
  });
  
  
  lab.experiment('Sites Plugin Read', () => {
  
      lab.beforeEach((done) => {
  
          request = {
              method: 'GET',
              url: '/sites/93EP150D35',
              credentials: AuthenticatedUser
          };
  
          done();
      });
  
  
      lab.test('it returns an error when find by id fails', (done) => {
  
          stub.Site.findOne = function (query, callback) {
  
              callback(Error('find by id failed'));
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(500);
              done();
          });
      });
  
  
      lab.test('it returns a not found when find by id misses', (done) => {
  
          stub.Site.findOne = function (query, callback) {
  
              callback();
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(404);
              Code.expect(response.result.message).to.match(/document not found/i);
  
              done();
          });
      });
  
  
      lab.test('it returns a document successfully', (done) => {
  
          stub.Site.findOne = function (query, callback) {
  
              callback(null, { _id: '93EP150D35' });
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(200);
              Code.expect(response.result).to.be.an.object();
  
              done();
          });
      });
  });
  
  
  lab.experiment('Sites Plugin Create', () => {
  
      lab.beforeEach((done) => {
  
          request = {
              method: 'POST',
              url: '/sites',
              payload: {
                  _id: 'thisgreatsite',
                  name: 'This Great Site As Well',
                  description: 'This is a great site for reasons.',
                  users: ['58b5e4040207ec3ba306a369']
              },
              credentials: AuthenticatedUser
          };
  
          done();
      });
  
  
      lab.test('it returns an error when create fails', (done) => {
  
          stub.Site.findOne = function (query, callback) {
  
              callback(Error('create failed'));
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(500);
              done();
          });
      });
  
  
      lab.test('it creates a document successfully', (done) => {
  
          stub.Site.findOne = function (query, callback) {
  
              callback(null, null);
          };
  
          stub.Site.create = function (_id, name, description, users, callback) {
  
              callback(null, {});
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(200);
              Code.expect(response.result).to.be.an.object();
  
              done();
          });
      });
  });
  
  
  lab.experiment('Statuses Plugin Update', () => {
  
      lab.beforeEach((done) => {
  
          request = {
              method: 'PUT',
              url: '/sites/thisgreatsite',
              payload: {
                  name: 'This Great Site',
                  description: 'This is a great site for reasons.',
                  users: ['58b5e4040207ec3ba306a269']
              },
              credentials: AuthenticatedUser
          };
  
          done();
      });
  
  
      lab.test('it returns an error when update fails', (done) => {
  
          stub.Site.findOneAndUpdate = function (query, update, callback) {
  
              callback(Error('update failed'));
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(500);
              done();
          });
      });
  
  
      lab.test('it returns not found when find by id misses', (done) => {
  
          stub.Site.findOneAndUpdate = function (query, update, callback) {
  
              callback(null, undefined);
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(404);
              done();
          });
      });
  
  
      lab.test('it updates a document successfully', (done) => {
  
          stub.Site.findOneAndUpdate = function (query, update, callback) {
  
              callback(null, {});
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(200);
              Code.expect(response.result).to.be.an.object();
  
              done();
          });
      });
  });
  
  
  lab.experiment('Statuses Plugin Delete', () => {
  
      lab.beforeEach((done) => {
  
          request = {
              method: 'DELETE',
              url: '/sites/93EP150D35',
              credentials: AuthenticatedUser
          };
  
          done();
      });
  
  
      lab.test('it returns an error when delete by id fails', (done) => {
  
          stub.Site.findOnedAndDelete = function (query, callback) {
  
              callback(Error('delete by id failed'));
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(500);
              done();
          });
      });
  
  
      lab.test('it returns a not found when delete by id misses', (done) => {
  
          stub.Site.findOnedAndDelete = function (query, callback) {
  
              callback(null, undefined);
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(404);
              Code.expect(response.result.message).to.match(/document not found/i);
  
              done();
          });
      });
  
  
      lab.test('it deletes a document successfully', (done) => {
  
          stub.Site.findOnedAndDelete = function (query, callback) {
  
              callback(null, 1);
          };
  
          server.inject(request, (response) => {
  
              Code.expect(response.statusCode).to.equal(200);
              Code.expect(response.result.message).to.match(/success/i);
  
              done();
          });
      });
  });
  