const express = require('express')
const app = express()
const chai = require('chai')
const expect = chai.expect
chai.use(require('chai-http'))

// Body Parser Middleware
app.use(express.json()) // Allows us to handle raw JSON data
app.use(express.urlencoded({ extended: false })) // Allows us to handle url encoded data
const middleware = require('../../../src/middleware/middleware')
app.use(middleware.createCtxAndReqUUID)

const getConstants = require('../../../src/constants').getConstants
const year22 = 2022
const errors = require('../../../src/controller/cve-id.controller/error')
const error = new errors.CveIdControllerError()

const cveIdFixtures = require('./mockObjects.cve-id')
const cveIdController = require('../../../src/controller/cve-id.controller/cve-id.controller')
const cveIdParams = require('../../../src/controller/cve-id.controller/cve-id.middleware')

class NullUserRepo {
  async getUserUUID () {
    return null
  }

  async findOneByUserNameAndOrgUUID () {
    return null
  }

  async isAdmin () {
    return null
  }
}

class NullOrgRepo {
  async findOneByShortName () {
    return null
  }

  async updateByOrgUUID () {
    return null
  }

  async getOrgUUID () {
    return null
  }

  async isSecretariat () {
    return null
  }

  async isSecretariatUUID () {
    return null
  }
}

describe('Testing the POST /cve-id-range/:year endpoint in CveId Controller', () => {
  context('Negative Tests', () => {
    it(`CveId Range already exists for year ${year22}`, (done) => {
      class CveIdRange2022Exists {
        constructor () {
          const CONSTANTS = getConstants()
          this.cveIdRange = Object.assign({}, CONSTANTS.DEFAULT_CVE_ID_RANGE)
          this.cveIdRange.cve_year = '2022'
        }

        async findOne () {
          return this.cveIdRange
        }
      }

      app.route('/cve-id-range-2022-already-exists/:year')
        .post((req, res, next) => {
          const factory = {
            getCveIdRangeRepository: () => { return new CveIdRange2022Exists() },
            getUserRepository: () => { return new NullUserRepo() },
            getOrgRepository: () => { return new NullOrgRepo() }
          }
          req.ctx.repositories = factory
          next()
        }, cveIdParams.parsePostParams, cveIdController.CVEID_RANGE_CREATE)

      chai.request(app)
        .post(`/cve-id-range-2022-already-exists/${year22}`)
        .set(cveIdFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(400)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.yearRangeExists(year22)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })
  })

  context('Positive Tests', () => {
    it(`CveId Range is created for year ${year22}`, (done) => {
      class CveIdRange2022NotExists {
        async findOne () {
          return null
        }

        async findOneAndUpdate () {
          return null
        }
      }

      app.route('/cve-id-range-2022/:year')
        .post((req, res, next) => {
          const factory = {
            getCveIdRangeRepository: () => { return new CveIdRange2022NotExists() },
            getUserRepository: () => { return new NullUserRepo() },
            getOrgRepository: () => { return new NullOrgRepo() }
          }
          req.ctx.repositories = factory
          next()
        }, cveIdParams.parsePostParams, cveIdController.CVEID_RANGE_CREATE)

      chai.request(app)
        .post(`/cve-id-range-2022/${year22}`)
        .set(cveIdFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          done()
        })
    })
  })
})
