text: const chai = require('chai');
  const chaiHttp = require('chai-http');
  const sinon = require('sinon');
  
  const sampleData = require('../../../sample-data');
  const TestHelper = require('../../../test-helper');
  
  const assert = chai.assert;
  const expect = chai.expect;
  
  chai.use(chaiHttp);
  
  describe('Integration - DELETE /incomes/:uuid', function() {
    let controllers;
    let models;
    let server;
    const testHelper = new TestHelper();
  
    let deleteIncomeSpy;
  
    let user1HouseholdMemberUuid;
    let user1IncomeUuid;
    let user1Token;
    let user1Uuid;
    let user2Token;
    let user2Uuid;
  
    before('get server', async function() {
      this.timeout(30000);
      const app = await testHelper.getApp();
      controllers = app.get('controllers');
      models = app.get('models');
      server = await testHelper.getServer();
    });
  
    before('create sinon spies', function() {
      deleteIncomeSpy = sinon.spy(controllers.IncomeCtrl, 'deleteIncome');
    });
  
    after('restore sinon spies', function() {
      deleteIncomeSpy.restore();
    });
  
    after('cleanup', async function() {
      await testHelper.cleanup();
    });
  
    beforeEach('create user 1', async function() {
      const apiCall = await models.Audit.ApiCall.create();
      user1Uuid = await controllers.UserCtrl.signUp({
        auditApiCallUuid: apiCall.get('uuid'),
        email: sampleData.users.user1.email,
        firstName: sampleData.users.user1.firstName,
        lastName: sampleData.users.user1.lastName,
        password: sampleData.users.user1.password,
      });
    });
  
    beforeEach('create user 1 token', async function() {
      user1Token = await controllers.UserCtrl.getToken(user1Uuid);
    });
  
    beforeEach('create user 1 household member', async function() {
      const apiCall = await models.Audit.ApiCall.create({
        user_uuid: user1Uuid,
      });
      user1HouseholdMemberUuid = await controllers.HouseholdCtrl.createMember({
        auditApiCallUuid: apiCall.get('uuid'),
        name: sampleData.users.user1.firstName,
      });
    });
  
    beforeEach('create user 1 income', async function() {
      const apiCall = await models.Audit.ApiCall.create({
        user_uuid: user1Uuid,
      });
      user1IncomeUuid = await controllers.IncomeCtrl.createIncome({
        amount: sampleData.incomes.income1.amount_cents,
        auditApiCallUuid: apiCall.get('uuid'),
        date: sampleData.incomes.income1.date,
        description: sampleData.incomes.income1.description,
        householdMemberUuid: user1HouseholdMemberUuid,
      });
    });
  
    beforeEach('create user 2', async function() {
      const apiCall = await models.Audit.ApiCall.create();
      user2Uuid = await controllers.UserCtrl.signUp({
        auditApiCallUuid: apiCall.get('uuid'),
        email: sampleData.users.user2.email,
        firstName: sampleData.users.user2.firstName,
        lastName: sampleData.users.user2.lastName,
        password: sampleData.users.user2.password,
      });
    });
  
    beforeEach('create user 2 token', async function() {
      user2Token = await controllers.UserCtrl.getToken(user2Uuid);
    });
  
    afterEach('reset history for sinon spies', function() {
      deleteIncomeSpy.resetHistory();
    });
  
    afterEach('truncate tables', async function() {
      this.timeout(10000);
      await testHelper.truncateTables();
    });
  
    it('should return 401 with no auth token', async function() {
      const res = await chai.request(server)
        .delete(`/incomes/${user1IncomeUuid}`)
        .set('Content-Type', 'application/vnd.api+json');
      expect(res).to.have.status(401);
      assert.deepEqual(res.body, {
        errors: [{
          detail: 'Unauthorized',
        }],
      });
      assert.strictEqual(deleteIncomeSpy.callCount, 0);
    });
  
    it('should return 404 with the wrong auth token', async function() {
      const res = await chai.request(server)
        .delete(`/incomes/${user1IncomeUuid}`)
        .set('Content-Type', 'application/vnd.api+json')
        .set('Authorization', `Bearer ${user2Token}`);
      expect(res).to.have.status(404);
      assert.deepEqual(res.body, {
        errors: [{
          detail: 'Unable to find income.',
        }],
      });
  
      assert.strictEqual(deleteIncomeSpy.callCount, 1);
      const deleteIncomeParams = deleteIncomeSpy.getCall(0).args[0];
      assert.isOk(deleteIncomeParams.auditApiCallUuid);
      assert.strictEqual(deleteIncomeParams.incomeUuid, user1IncomeUuid);
    });
  
    it('should return 204 with the correct auth token', async function() {
      const res = await chai.request(server)
        .delete(`/incomes/${user1IncomeUuid}`)
        .set('Content-Type', 'application/vnd.api+json')
        .set('Authorization', `Bearer ${user1Token}`);
      expect(res).to.have.status(204);
      assert.deepEqual(res.body, {});
  
      // Validate IncomeCtrl.deleteIncome call.
      assert.strictEqual(deleteIncomeSpy.callCount, 1);
      const deleteIncomeParams = deleteIncomeSpy.getCall(0).args[0];
      assert.isOk(deleteIncomeParams.auditApiCallUuid);
      assert.strictEqual(deleteIncomeParams.incomeUuid, user1IncomeUuid);
  
      // Validate Audit API call.
      const apiCall = await models.Audit.ApiCall.findOne({
        attributes: [
          'http_method',
          'ip_address',
          'route',
          'user_agent',
          'user_uuid',
          'uuid',
        ],
        where: {
          uuid: deleteIncomeParams.auditApiCallUuid,
        },
      });
      assert.isOk(apiCall);
      assert.strictEqual(apiCall.get('http_method'), 'DELETE');
      assert.isOk(apiCall.get('ip_address'));
      assert.strictEqual(apiCall.get('route'), `/incomes/${user1IncomeUuid}`);
      assert.isOk(apiCall.get('user_agent'));
      assert.strictEqual(apiCall.get('user_uuid'), user1Uuid);
    });
  });
  