text:
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 year20 = 2020
const year21 = 2021
const getConstants = require('../../../../src/constants').getConstants
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 OrgReserveYear2025RangeDoesntExistSequential {
  async isSecretariat () {
    return true
  }

  async findOneByShortName () {
    return cveIdFixtures.owningOrg
  }

  async findOneAndUpdate (query) {
    if (query.short_name === cveIdFixtures.owningOrg.short_name && cveIdFixtures.owningOrg.inUse === false) {
      cveIdFixtures.owningOrg.inUse = true
      return cveIdFixtures.owningOrg
    } else if (query.short_name === cveIdFixtures.owningOrg.short_name && cveIdFixtures.owningOrg.inUse === true) {
      cveIdFixtures.owningOrg.inUse = false
      return null
    }
  }
}

describe('Testing the sequential reservation of POST /cve-id endpoint in CveId Controller', () => {
  context('Negative Tests', () => {
    it('CveId Range document for year 2025 does not exist', (done) => {
      class CveIdReserveSequentialYearDoesntExist {
        async countDocuments () {
          return 2
        }
      }

      class CveIdRangeReserveYearDoesntExist {
        async findOne () {
          return null
        }
      }

      app.route('/cve-id-reserve-2025-doesnt-exist-sequential')
        .post((req, res, next) => {
          const factory = {
            getCveIdRepository: () => { return new CveIdReserveSequentialYearDoesntExist() },
            getCveIdRangeRepository: () => { return new CveIdRangeReserveYearDoesntExist() },
            getUserRepository: () => { return new NullUserRepo() },
            getOrgRepository: () => { return new OrgReserveYear2025RangeDoesntExistSequential() }
          }
          req.ctx.repositories = factory
          next()
        }, cveIdParams.parsePostParams, cveIdController.CVEID_RESERVE)

      chai.request(app)
        .post(`/cve-id-reserve-2025-doesnt-exist-sequential?short_name=${cveIdFixtures.owningOrg.short_name}&cve_year=2025&amount=5&batch_type=sequential`)
        .set(cveIdFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          const quotaHeader = (cveIdFixtures.owningOrg.policies.id_quota - 2).toString()
          expect(res.header).to.have.property('cve-api-remaining-quota').and.to.equal(quotaHeader)

          expect(res).to.have.status(403)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.cannotReserveForYear('2025')
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('CveId Range document for year 2021 is full', (done) => {
      const CONSTANTS = getConstants()

      class CveIdReserveSequentialIsFull {
        async countDocuments () {
          return 2
        }
      }

      class CveIdRangeReserveSequentialIsFull {
        constructor () {
          this.year = '2021'
          this.cveIdRange = Object.assign({}, CONSTANTS.DEFAULT_CVE_ID_RANGE)
          this.cveIdRange.cve_year = this.year
          this.cveIdRange.ranges.priority.top_id = this.cveIdRange.ranges.priority.end
          this.cveIdRange.ranges.general.top_id = this.cveIdRange.ranges.general.end
        }

        async findOne () {
          return this.cveIdRange
        }

        async findOneAndUpdate () {
          return null
        }
      }

      app.route('/cve-id-reserve-2021-full-sequential')
        .post((req, res, next) => {
          const factory = {
            getCveIdRepository: () => { return new CveIdReserveSequentialIsFull() },
            getCveIdRangeRepository: () => { return new CveIdRangeReserveSequentialIsFull() },
            getUserRepository: () => { return new NullUserRepo() },
            getOrgRepository: () => { return new OrgReserveYear2025RangeDoesntExistSequential() }
          }
          req.ctx.repositories = factory
          next()
        }, cveIdParams.parsePostParams, cveIdController.CVEID_RESERVE)

      chai.request(app)
        .post(`/cve-id-reserve-2021-full-sequential?short_name=${cveIdFixtures.owningOrg.short_name}&cve_year=${year21}&amount=10&batch_type=sequential`)
        .set(cveIdFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          const quotaHeader = (cveIdFixtures.owningOrg.policies.id_quota - 2).toString()
          expect(res.header).to.have.property('cve-api-remaining-quota').and.to.equal(quotaHeader)

          expect(res).to.have.status(403)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.yearRangeFull(year21)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })
  })

  context('Positive Tests', () => {
    it('Cve IDs are reserved for year 2020', (done) => {
      const CONSTANTS = getConstants()

      class CveIdReserveSequential {
        async insertMany () {
          return null
        }

        async countDocuments () {
          return 2
        }
      }

      class CveIdRangeReserveSequential {
        constructor () {
          this.year = '2020'
          this.cveIdRange = Object.assign({}, CONSTANTS.DEFAULT_CVE_ID_RANGE)
          this.cveIdRange.cve_year = this.year
          this.cveIdRange.ranges.priority.top_id = 2 // already has two reserved cve ids
          this.cveIdRange.ranges.priority.end = 10
          this.cveIdRange.ranges.general.top_id = this.cveIdRange.ranges.priority.end
          this.cveIdRange.ranges.general.start = this.cveIdRange.ranges.general.top_id
          this.cveIdRange.ranges.general.end = 15
        }

        async findOne () {
          return this.cveIdRange
        }

        async findOneAndUpdate (query, set) {
          if (query.$and[0].cve_year === this.year && query.$and[1]['ranges.general.end'] !== undefined &&
          this.cveIdRange.ranges.general.end > this.cveIdRange.ranges.general.top_id + 5 - 1) {
            this.cveIdRange.ranges.general.top_id += set.$inc['ranges.general.top_id']
            return this.cveIdRange
          }

          return null
        }
      }

      class UserReserveSequentialPriorityIsFull {
        async findOneByUserNameAndOrgUUID () {
          return cveIdFixtures.owningOrgUser
        }
      }

      class OrgReserveSequentialPriorityIsFull {
        async isSecretariat () {
          return false
        }

        async findOneByShortName () {
          return cveIdFixtures.owningOrg
        }

        async findOneAndUpdate (query) {
          if (query.short_name === cveIdFixtures.owningOrg.short_name && cveIdFixtures.owningOrg.inUse === false) {
            cveIdFixtures.owningOrg.inUse = true
            return cveIdFixtures.owningOrg
          } else if (query.short_name === cveIdFixtures.owningOrg.short_name && cveIdFixtures.owningOrg.inUse === true) {
            cveIdFixtures.owningOrg.inUse = false
            return null
          }
        }

        async getOrgUUID () {
          return cveIdFixtures.owningOrg.UUID
        }
      }

      app.route('/cve-id-reserve-2020-sequential')
        .post((req, res, next) => {
          const factory = {
            getCveIdRepository: () => { return new CveIdReserveSequential() },
            getCveIdRangeRepository: () => { return new CveIdRangeReserveSequential() },
            getUserRepository: () => { return new UserReserveSequentialPriorityIsFull() },
            getOrgRepository: () => { return new OrgReserveSequentialPriorityIsFull() }
          }
          req.ctx.repositories = factory
          next()
        }, cveIdParams.parsePostParams, cveIdController.CVEID_RESERVE)

      const top = 10
      let counter = 1

      chai.request(app)
        .post(`/cve-id-reserve-2020-sequential?short_name=${cveIdFixtures.owningOrg.short_name}&cve_year=${year20}&amount=5&batch_type=sequential`)
        .set(cveIdFixtures.owningOrgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          const quotaHeader = (cveIdFixtures.owningOrg.policies.id_quota - 7).toString() // already has two reserved cve ids
          expect(res.header).to.have.property('cve-api-remaining-quota').and.to.equal(quotaHeader)

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('cve_ids').and.to.be.a('array').and.to.have.lengthOf(5)
          res.body.cve_ids.forEach(obj => {
            const count = String(top + counter).padStart(4, '0')
            expect(obj).to.have.property('cve_id').and.to.equal(`CVE-${year20}-${count}`) // check that cve ids are sequential
            expect(obj).to.have.property('state').and.to.equal('RESERVED')
            expect(obj).to.have.property('owning_cna').and.to.equal(cveIdFixtures.owningOrg.short_name)
            expect(obj).to.have.nested.property('requested_by.cna').and.to.equal(cveIdFixtures.owningOrg.short_name)
            expect(obj).to.have.nested.property('requested_by.user').and.to.equal(cveIdFixtures.owningOrgUser.username)
            counter++
          })
          done()
        })
    })
  })
})


text:
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 errors = require('../../../src/controller/org.controller/error')
const error = new errors.OrgControllerError()

const userFixtures = require('./mockObjects.user')
const orgController = require('../../../src/controller/org.controller/org.controller')
const orgParams = require('../../../src/controller/org.controller/org.middleware')

class OrgUserNotUpdatedOrgQueryDoesntExist {
  async getOrgUUID (shortname) {
    if (shortname === userFixtures.existentOrg.short_name) {
      return userFixtures.existentOrg.UUID
    }
    return null
  }

  async isSecretariat () {
    return true
  }
}

class OrgUserUpdatedAddingRole {
  async getOrgUUID () {
    return userFixtures.owningOrg.UUID
  }

  async isSecretariat () {
    return true
  }
}

class UserUpdatedAddingRole {
  constructor () {
    this.user = {
      org_UUID: userFixtures.existentUserDummy.org_UUID,
      username: userFixtures.existentUserDummy.username,
      UUID: userFixtures.existentUserDummy.UUID,
      active: userFixtures.existentUserDummy.active,
      name: userFixtures.existentUserDummy.name,
      authority: {
        active_roles: []
      },
      secret: userFixtures.existentUserDummy.secret
    }

    const CONSTANTS = getConstants()

    this.testRes1 = JSON.parse(JSON.stringify(userFixtures.existentUserDummy))
    this.testRes1.authority.active_roles = [CONSTANTS.USER_ROLE_ENUM.ADMIN]
  }

  getUser () {
    const CONSTANTS = getConstants()

    this.user.authority.active_roles.push(CONSTANTS.USER_ROLE_ENUM.ADMIN)
    return this.user
  }

  async findOneByUserNameAndOrgUUID () {
    return this.user
  }

  async updateByUserNameAndOrgUUID () {
    return { n: 1, nModified: 1, ok: 1 }
  }

  async getUserUUID () {
    return this.user.UUID
  }

  async isAdmin () {
    return true
  }

  async aggregate () {
    return [this.testRes1]
  }
}

describe('Testing the PUT /org/:shortname/user/:username endpoint in Org Controller', () => {
  context('Negative Tests', () => {
    it('User is not updated because org does not exist', (done) => {
      class OrgUserNotUpdatedOrgDoesntExist {
        async getOrgUUID () {
          return null
        }

        async isSecretariat () {
          return true
        }
      }

      class NullUserRepo {
        async getUserUUID () {
          return null
        }

        async findOneByUserNameAndOrgUUID () {
          return null
        }

        async isAdmin () {
          return null
        }
      }

      app.route('/user-not-updated-org-doesnt-exist/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserNotUpdatedOrgDoesntExist() },
            getUserRepository: () => { return new NullUserRepo() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      const shortname = userFixtures.nonExistentOrg.short_name.replace(/\s/g, '')
      const username = userFixtures.existentUser.username.replace(/\s/g, '')
      chai.request(app)
        .put(`/user-not-updated-org-doesnt-exist/${shortname}/${username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.orgDnePathParam(userFixtures.nonExistentOrg.short_name)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('User is not updated because user does not exist', (done) => {
      class OrgUserNotUpdatedUserDoesntExist {
        async getOrgUUID () {
          return userFixtures.existentOrg
        }

        async isSecretariat () {
          return true
        }
      }

      class UserNotUpdatedUserDoesntExist {
        async findOneByUserNameAndOrgUUID () {
          return null
        }

        async isAdmin () {
          return null
        }
      }

      app.route('/user-not-updated-doesnt-exist/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserNotUpdatedUserDoesntExist() },
            getUserRepository: () => { return new UserNotUpdatedUserDoesntExist() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      const shortname = userFixtures.existentOrg.short_name.replace(/\s/g, '')
      const username = userFixtures.nonExistentUser.username.replace(/\s/g, '')
      chai.request(app)
        .put(`/user-not-updated-doesnt-exist/${shortname}/${username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.userDne(userFixtures.nonExistentUser.username)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('User is not updated because the new shortname does not exist', (done) => {
      class UserNotUpdatedOrgQueryDoesntExist {
        async findOneByUserNameAndOrgUUID () {
          return userFixtures.existentUser
        }

        async isAdmin () {
          return null
        }
      }

      app.route('/user-not-updated-user-doesnt-exist/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserNotUpdatedOrgQueryDoesntExist() },
            getUserRepository: () => { return new UserNotUpdatedOrgQueryDoesntExist() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      chai.request(app)
        .put(`/user-not-updated-user-doesnt-exist/${userFixtures.existentOrg.short_name}/${userFixtures.existentUser.username}?org_short_name=${userFixtures.nonExistentOrg.short_name}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.orgDne(userFixtures.nonExistentOrg.short_name, 'org_short_name', 'query')
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('User is not updated because requestor is not Org Admin, Secretariat, or user', (done) => {
      class Org {
        async getOrgUUID () {
          return userFixtures.existentOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class User {
        async findOneByUserNameAndOrgUUID () {
          return userFixtures.existentUser
        }

        async isAdmin () {
          return false
        }
      }

      app.route('/user-not-updated-requestor-not-admin-secretariat-user/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new Org() },
            getUserRepository: () => { return new User() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      chai.request(app)
        .put(`/user-not-updated-requestor-not-admin-secretariat-user/${userFixtures.existentOrg.short_name}/${userFixtures.existentUser.username}?org_short_name=${userFixtures.existentOrg.short_name}`)
        .set(userFixtures.owningOrgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

    it('User is not updated because Org Admin is trying to change organization', (done) => {
      class Org {
        async getOrgUUID () {
          return userFixtures.existentOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class User {
        async findOneByUserNameAndOrgUUID () {
          return userFixtures.existentUser
        }

        async isAdmin () {
          return true
        }
      }

      app.route('/user-not-updated-admin-changing-org/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new Org() },
            getUserRepository: () => { return new User() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      chai.request(app)
        .put(`/user-not-updated-admin-changing-org/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userA.username}?org_short_name=${userFixtures.existentOrgDummy.short_name}`)
        .set(userFixtures.userDHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

    it('User is not updated because requestor is Org Admin of different organization', (done) => {
      class Org {
        async getOrgUUID () {
          return userFixtures.existentOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class User {
        async findOneByUserNameAndOrgUUID () {
          return userFixtures.existentUser
        }

        async isAdmin (username, shortname) {
          expect(username).to.equal(userFixtures.userDHeader['CVE-API-USER'])
          expect(shortname).to.equal(userFixtures.existentOrgDummy.short_name)
          return true
        }
      }

      app.route('/user-not-updated-requestor-different-admin/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new Org() },
            getUserRepository: () => { return new User() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      chai.request(app)
        .put(`/user-not-updated-requestor-different-admin/${userFixtures.existentOrg.short_name}/${userFixtures.existentUser.username}?org_short_name=${userFixtures.existentOrg.short_name}`)
        .set(userFixtures.userDHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

    it('User is not updated because user can\'t update their own active field', (done) => {
      class Org {
        async getOrgUUID () {
          return userFixtures.existentOrgDummy.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class User {
        async findOneByUserNameAndOrgUUID () {
          return userFixtures.userA
        }

        async isAdmin (username, shortname) {
          expect(username).to.equal(userFixtures.userAHeader['CVE-API-USER'])
          expect(shortname).to.equal(userFixtures.existentOrgDummy.short_name)
          return false
        }
      }

      app.route('/user-not-updated-cant-update-active-field/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new Org() },
            getUserRepository: () => { return new User() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      chai.request(app)
        .put(`/user-not-updated-cant-update-active-field/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userA.username}?active=true`)
        .set(userFixtures.userAHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

  context('Positive Tests', () => {
    it('User is updated: Adding a user role', (done) => {
      app.route('/user-updated-adding-role-1/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserUpdatedAddingRole() },
            getUserRepository: () => { return new UserUpdatedAddingRole() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      const CONSTANTS = getConstants()
      const testUser = Object.assign({}, userFixtures.existentUserDummy)
      testUser.authority = {
        active_roles: [CONSTANTS.USER_ROLE_ENUM.ADMIN]
      }

      chai.request(app)
        .put(`/user-updated-adding-role-1/${userFixtures.owningOrg.short_name}/${testUser.username}?active_roles.add=${CONSTANTS.USER_ROLE_ENUM.ADMIN}&active_roles.add=${CONSTANTS.USER_ROLE_ENUM.ADMIN}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('updated').and.to.be.a('object')
          expect(res.body.updated.authority.active_roles).to.have.lengthOf(1)
          expect(res.body.updated.authority.active_roles[0]).to.equal(testUser.authority.active_roles[0])
          expect(res.body.updated.org_UUID).to.equal(testUser.org_UUID)
          expect(res.body.updated.username).to.equal(testUser.username)
          expect(res.body.updated.UUID).to.equal(testUser.UUID)
          expect(res.body.updated.secret).to.equal(testUser.secret)
          expect(res.body.updated.active).to.equal(testUser.active)
          expect(res.body.updated.name.first).to.equal(testUser.name.first)
          expect(res.body.updated.name.last).to.equal(testUser.name.last)
          expect(res.body.updated.name.middle).to.equal(testUser.name.middle)
          expect(res.body.updated.name.suffix).to.equal(testUser.name.suffix)
          done()
        })
    })

    it('User is unchanged: Adding a user role that the user already have', (done) => {
      class UserUpdatedAddingRoleAlreadyExists {
        constructor () {
          const CONSTANTS = getConstants()

          this.user = {
            org_UUID: userFixtures.existentUserDummy.org_UUID,
            username: userFixtures.existentUserDummy.username,
            UUID: userFixtures.existentUserDummy.UUID,
            active: userFixtures.existentUserDummy.active,
            name: userFixtures.existentUserDummy.name,
            authority: {
              active_roles: [CONSTANTS.USER_ROLE_ENUM.ADMIN]
            },
            secret: userFixtures.existentUserDummy.secret
          }

          this.testRes1 = JSON.parse(JSON.stringify(userFixtures.existentUserDummy))
          this.testRes1.authority.active_roles = [CONSTANTS.USER_ROLE_ENUM.ADMIN]
        }

        getUser () {
          return this.user
        }

        async findOneByUserNameAndOrgUUID () {
          return this.user
        }

        async updateByUserNameAndOrgUUID () {
          return { n: 1, nModified: 1, ok: 1 }
        }

        async getUserUUID () {
          return this.user.UUID
        }

        async isAdmin () {
          return false
        }

        async aggregate () {
          return [this.testRes1]
        }
      }

      app.route('/user-updated-adding-role-2/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserUpdatedAddingRole() },
            getUserRepository: () => { return new UserUpdatedAddingRoleAlreadyExists() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      const CONSTANTS = getConstants()
      const testUser = Object.assign({}, userFixtures.existentUserDummy)
      testUser.authority = {
        active_roles: [CONSTANTS.USER_ROLE_ENUM.ADMIN]
      }

      chai.request(app)
        .put(`/user-updated-adding-role-2/${userFixtures.owningOrg.short_name}/${testUser.username}?active_roles.add=${CONSTANTS.USER_ROLE_ENUM.ADMIN}&active_roles.add=${CONSTANTS.USER_ROLE_ENUM.ADMIN}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('updated').and.to.be.a('object')
          expect(res.body.updated.authority.active_roles).to.have.lengthOf(1)
          expect(res.body.updated.authority.active_roles[0]).to.equal(testUser.authority.active_roles[0])
          expect(res.body.updated.org_UUID).to.equal(testUser.org_UUID)
          expect(res.body.updated.username).to.equal(testUser.username)
          expect(res.body.updated.UUID).to.equal(testUser.UUID)
          expect(res.body.updated.secret).to.equal(testUser.secret)
          expect(res.body.updated.active).to.equal(testUser.active)
          expect(res.body.updated.name.first).to.equal(testUser.name.first)
          expect(res.body.updated.name.last).to.equal(testUser.name.last)
          expect(res.body.updated.name.middle).to.equal(testUser.name.middle)
          expect(res.body.updated.name.suffix).to.equal(testUser.name.suffix)
          done()
        })
    })

    it('User is updated: Removing a user role', (done) => {
      class UserUpdatedRemovingRole {
        constructor () {
          const CONSTANTS = getConstants()

          this.user = {
            org_UUID: userFixtures.existentUserDummy.org_UUID,
            username: userFixtures.existentUserDummy.username,
            UUID: userFixtures.existentUserDummy.UUID,
            active: userFixtures.existentUserDummy.active,
            name: userFixtures.existentUserDummy.name,
            authority: {
              active_roles: [CONSTANTS.USER_ROLE_ENUM.ADMIN]
            },
            secret: userFixtures.existentUserDummy.secret
          }

          this.testRes1 = JSON.parse(JSON.stringify(userFixtures.existentUserDummy))
          this.testRes1.authority.active_roles = []
        }

        getUser () {
          this.user.authority.active_roles.splice(0, 1)
          return this.user
        }

        async findOneByUserNameAndOrgUUID () {
          return this.user
        }

        async updateByUserNameAndOrgUUID () {
          return { n: 1, nModified: 1, ok: 1 }
        }

        async getUserUUID () {
          return this.user.UUID
        }

        async isAdmin () {
          return false
        }

        async aggregate () {
          return [this.testRes1]
        }
      }

      app.route('/user-updated-removing-role-1/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserUpdatedAddingRole() },
            getUserRepository: () => { return new UserUpdatedRemovingRole() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      const CONSTANTS = getConstants()
      const testUser = Object.assign({}, userFixtures.existentUserDummy)
      testUser.authority = {
        active_roles: [CONSTANTS.USER_ROLE_ENUM.ADMIN]
      }

      chai.request(app)
        .put(`/user-updated-removing-role-1/${userFixtures.owningOrg.short_name}/${testUser.username}?active_roles.remove=${CONSTANTS.USER_ROLE_ENUM.ADMIN}&active_roles.remove=${CONSTANTS.USER_ROLE_ENUM.ADMIN}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('updated').and.to.be.a('object')
          expect(res.body.updated.authority.active_roles).to.have.lengthOf(0)
          expect(res.body.updated.org_UUID).to.equal(testUser.org_UUID)
          expect(res.body.updated.username).to.equal(testUser.username)
          expect(res.body.updated.UUID).to.equal(testUser.UUID)
          expect(res.body.updated.secret).to.equal(testUser.secret)
          expect(res.body.updated.active).to.equal(testUser.active)
          expect(res.body.updated.name.first).to.equal(testUser.name.first)
          expect(res.body.updated.name.last).to.equal(testUser.name.last)
          expect(res.body.updated.name.middle).to.equal(testUser.name.middle)
          expect(res.body.updated.name.suffix).to.equal(testUser.name.suffix)
          done()
        })
    })

    it('User is unchanged: Removing a user role that the user does not have', (done) => {
      class UserUpdatedRemovingRoleAlreadyRemoved {
        constructor () {
          this.user = {
            org_UUID: userFixtures.existentUserDummy.org_UUID,
            username: userFixtures.existentUserDummy.username,
            UUID: userFixtures.existentUserDummy.UUID,
            active: userFixtures.existentUserDummy.active,
            name: userFixtures.existentUserDummy.name,
            authority: userFixtures.existentUserDummy.authority,
            secret: userFixtures.existentUserDummy.secret
          }
        }

        getUser () {
          return this.user
        }

        async findOneByUserNameAndOrgUUID () {
          return this.user
        }

        async updateByUserNameAndOrgUUID () {
          return { n: 1, nModified: 1, ok: 1 }
        }

        async getUserUUID () {
          return this.user.UUID
        }

        async isAdmin () {
          return false
        }

        async aggregate () {
          return [this.user]
        }
      }

      app.route('/user-updated-removing-role-2/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserUpdatedAddingRole() },
            getUserRepository: () => { return new UserUpdatedRemovingRoleAlreadyRemoved() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      const CONSTANTS = getConstants()

      chai.request(app)
        .put(`/user-updated-removing-role-2/${userFixtures.owningOrg.short_name}/${userFixtures.existentUserDummy.username}?active_roles.remove=${CONSTANTS.USER_ROLE_ENUM.ADMIN}&active_roles.remove=${CONSTANTS.USER_ROLE_ENUM.ADMIN}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('updated').and.to.be.a('object')
          expect(res.body.updated.authority.active_roles).to.have.lengthOf(0)
          expect(res.body.updated.org_UUID).to.equal(userFixtures.existentUserDummy.org_UUID)
          expect(res.body.updated.username).to.equal(userFixtures.existentUserDummy.username)
          expect(res.body.updated.UUID).to.equal(userFixtures.existentUserDummy.UUID)
          expect(res.body.updated.secret).to.equal(userFixtures.existentUserDummy.secret)
          expect(res.body.updated.active).to.equal(userFixtures.existentUserDummy.active)
          expect(res.body.updated.name.first).to.equal(userFixtures.existentUserDummy.name.first)
          expect(res.body.updated.name.last).to.equal(userFixtures.existentUserDummy.name.last)
          expect(res.body.updated.name.middle).to.equal(userFixtures.existentUserDummy.name.middle)
          expect(res.body.updated.name.suffix).to.equal(userFixtures.existentUserDummy.name.suffix)
          done()
        })
    })

    it('User is updated: Deactivating User as Admin', (done) => {
      class Org {
        async getOrgUUID () {
          return userFixtures.existentOrgDummy.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class User {
        constructor () {
          this.testRes1 = JSON.parse(JSON.stringify(userFixtures.userA))
          this.testRes1.active = false
        }

        async findOneByUserNameAndOrgUUID () {
          return userFixtures.userA
        }

        async isAdmin (username, shortname) {
          expect(username).to.equal(userFixtures.userDHeader['CVE-API-USER'])
          expect(shortname).to.equal(userFixtures.existentOrgDummy.short_name)
          return true
        }

        async updateByUserNameAndOrgUUID () {
          return { n: 1 }
        }

        async getUserUUID () {
          return userFixtures.userD.UUID
        }

        async aggregate () {
          return [this.testRes1]
        }
      }

      app.route('/user-updated-requestor-admin-deactivate-user/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new Org() },
            getUserRepository: () => { return new User() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      chai.request(app)
        .put(`/user-updated-requestor-admin-deactivate-user/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userA.username}?active=false`)
        .set(userFixtures.userDHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('updated').and.to.be.a('object')
          expect(res.body.updated.active).to.equal(false)
          done()
        })
    })

    it('User is updated: Username changed as user', (done) => {
      class Org {
        async getOrgUUID () {
          return userFixtures.existentOrgDummy.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class User {
        constructor () {
          this.testRes1 = JSON.parse(JSON.stringify(userFixtures.userA))
          this.testRes1.username = 'TESTER'
        }

        async findOneByUserNameAndOrgUUID () {
          return userFixtures.userA
        }

        async isAdmin (username, shortname) {
          expect(username).to.equal(userFixtures.userAHeader['CVE-API-USER'])
          expect(shortname).to.equal(userFixtures.existentOrgDummy.short_name)
          return true
        }

        async updateByUserNameAndOrgUUID () {
          return { n: 1 }
        }

        async getUserUUID () {
          return userFixtures.userA.UUID
        }

        async find () {
          return []
        }

        async aggregate () {
          return [this.testRes1]
        }
      }

      app.route('/user-updated-requestor-user-username-changed/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new Org() },
            getUserRepository: () => { return new User() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      chai.request(app)
        .put(`/user-updated-requestor-user-username-changed/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userA.username}?new_username=TESTER`)
        .set(userFixtures.userAHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('updated').and.to.be.a('object')
          expect(res.body.updated.username).to.equal('TESTER')
          done()
        })
    })

    it('User is unchanged: No query parameters are provided', async () => {
      class UserNotUpdatedNoQuery {
        async findOneByUserNameAndOrgUUID () {
          return userFixtures.existentUser
        }

        async updateByUserNameAndOrgUUID () {
          return { n: 1, nModified: 1, ok: 1 }
        }

        async getUserUUID () {
          return userFixtures.existentUser.UUID
        }

        async isAdmin () {
          return false
        }

        async aggregate () {
          return [userFixtures.existentUser]
        }
      }

      app.route('/user-not-updated-no-parameters/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserNotUpdatedOrgQueryDoesntExist() },
            getUserRepository: () => { return new UserNotUpdatedNoQuery() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_UPDATE_SINGLE)

      const res = await chai.request(app)
        .put(`/user-not-updated-no-parameters/${userFixtures.existentOrg.short_name}/${userFixtures.existentUser.username}`)
        .set(userFixtures.secretariatHeader)

      expect(res).to.have.status(200)
      expect(res).to.have.property('body').and.to.be.a('object')
      expect(res.body).to.have.property('updated').and.to.be.a('object')
      expect(res.body.updated.authority.active_roles[0]).to.equal(userFixtures.existentUser.authority.active_roles[0])
      expect(res.body.updated.org_UUID).to.equal(userFixtures.existentUser.org_UUID)
      expect(res.body.updated.username).to.equal(userFixtures.existentUser.username)
      expect(res.body.updated.UUID).to.equal(userFixtures.existentUser.UUID)
      expect(res.body.updated.secret).to.equal(userFixtures.existentUser.secret)
      expect(res.body.updated.active).to.equal(userFixtures.existentUser.active)
      expect(res.body.updated.name.first).to.equal(userFixtures.existentUser.name.first)
      expect(res.body.updated.name.last).to.equal(userFixtures.existentUser.name.last)
      expect(res.body.updated.name.middle).to.equal(userFixtures.existentUser.name.middle)
      expect(res.body.updated.name.suffix).to.equal(userFixtures.existentUser.name.suffix)
    })
  })
})

repo_name: CVEProject/cve-services

repo_language: JavaScript

file_name: Dockerfile

mime_type: text/plain


text:
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 errors = require('../../../src/controller/org.controller/error')
const error = new errors.OrgControllerError()

const userFixtures = require('./mockObjects.user')
const orgController = require('../../../src/controller/org.controller/org.controller')
const orgParams = require('../../../src/controller/org.controller/org.middleware')

class OrgGetUser {
  async isSecretariat (shortname) {
    return shortname === userFixtures.existentOrg.short_name
  }

  async getOrgUUID (shortname) {
    if (shortname === userFixtures.existentOrg.short_name) {
      return userFixtures.existentOrg.UUID
    } else if (shortname === userFixtures.owningOrg.short_name) {
      return userFixtures.owningOrg.UUID
    }

    return null
  }
}

class UserGetUser {
  async aggregate (aggregation) {
    if (aggregation[0].$match.username === userFixtures.existentUser.username &&
      aggregation[0].$match.org_UUID === userFixtures.existentUser.org_UUID) {
      return [userFixtures.existentUser]
    } else if (aggregation[0].$match.username === userFixtures.existentUserDummy.username &&
      aggregation[0].$match.org_UUID === userFixtures.existentUserDummy.org_UUID) {
      return [userFixtures.existentUserDummy]
    }

    return []
  }
}

describe('Testing the GET /org/:shortname/user/:username endpoint in Org Controller', () => {
  context('Negative Tests', () => {
    it('Org does not exists', (done) => {
      class OrgGetUserOrgDoesntExist {
        async isSecretariat () {
          return true
        }

        async getOrgUUID () {
          return null
        }
      }

      class NullUserRepo {
        async getUserUUID () {
          return null
        }

        async findOneByUserNameAndOrgUUID () {
          return null
        }

        async isAdmin () {
          return null
        }
      }

      app.route('/user-get-user-org-doesnt-exist/:shortname/:username')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgGetUserOrgDoesntExist() },
            getUserRepository: () => { return new NullUserRepo() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_SINGLE)

      chai.request(app)
        .get(`/user-get-user-org-doesnt-exist/${userFixtures.nonExistentOrg.short_name}/${userFixtures.existentUser.username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.orgDnePathParam(userFixtures.nonExistentOrg.short_name)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('User does not exists', (done) => {
      class UserGetUserDoesntExist {
        async aggregate () {
          return []
        }
      }

      app.route('/user-get-user-user-doesnt-exist/:shortname/:username')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgGetUser() },
            getUserRepository: () => { return new UserGetUserDoesntExist() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_SINGLE)

      chai.request(app)
        .get(`/user-get-user-user-doesnt-exist/${userFixtures.existentOrg.short_name}/${userFixtures.nonExistentUser.username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.userDne(userFixtures.nonExistentUser.username)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('User exists and the requester is not secretariat and does not belong to the user\'s org', (done) => {
      app.route('/user-get-user/:shortname/:username')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgGetUser() },
            getUserRepository: () => { return new UserGetUser() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_SINGLE)

      chai.request(app)
        .get(`/user-get-user/${userFixtures.owningOrg.short_name}/${userFixtures.existentUserDummy.username}`)
        .set(userFixtures.orgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

  context('Positive Tests', () => {
    it('User exists and the requester is the secretariat', (done) => {
      app.route('/user-get-user/:shortname/:username')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgGetUser() },
            getUserRepository: () => { return new UserGetUser() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_SINGLE)

      chai.request(app)
        .get(`/user-get-user/${userFixtures.existentOrg.short_name}/${userFixtures.existentUser.username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('username').and.to.equal(userFixtures.existentUser.username)
          expect(res.body).to.have.property('org_UUID').and.to.equal(userFixtures.existentUser.org_UUID)
          done()
        })
    })

    it('User exists and the requester belongs to the user\'s org', (done) => {
      app.route('/user-get-user/:shortname/:username')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgGetUser() },
            getUserRepository: () => { return new UserGetUser() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_SINGLE)

      chai.request(app)
        .get(`/user-get-user/${userFixtures.owningOrg.short_name}/${userFixtures.existentUserDummy.username}`)
        .set(userFixtures.owningOrgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('username').and.to.equal(userFixtures.existentUserDummy.username)
          expect(res.body).to.have.property('org_UUID').and.to.equal(userFixtures.existentUserDummy.org_UUID)
          done()
        })
    })
  })
})


text:
const getConstants = require('../../../src/constants').getConstants
const CONSTANTS = getConstants()

const secretariatHeader = {
  'content-type': 'application/json',
  'CVE-API-ORG': 'mitre',
  'CVE-API-USER': 'cpadro',
  'CVE-API-KEY': 'S96E4QT-SMT4YE3-KX03X6K-4615CED'
}

const owningOrgHeader = {
  'content-type': 'application/json',
  'CVE-API-ORG': 'cisco',
  'CVE-API-USER': 'alopez',
  'CVE-API-KEY': 'SVXPHM9-1VXM0A8-QMG8WN0-29MASSE'
}

const orgHeader = {
  'content-type': 'application/json',
  'CVE-API-ORG': 'apple',
  'CVE-API-USER': 'rgonz',
  'CVE-API-KEY': 'NKWE9PE-42B472A-M5A9W3G-80C31B7'
}

const userAHeader = {
  'content-type': 'application/json',
  'CVE-API-ORG': 'google',
  'CVE-API-USER': 'abaker',
  'CVE-API-KEY': 'TCF25YM-39C4H6D-KA32EGF-V5XSHN3'
}

// admin user header
const userDHeader = {
  'content-type': 'application/json',
  'CVE-API-ORG': 'google',
  'CVE-API-USER': 'gsmith',
  'CVE-API-KEY': 'TCF25YM-39C4H6D-KA32EGF-V5XSHN3'
}

const existentOrg = {
  UUID: '15fd129f-af00-4d8c-8f7b-e19b0587223f',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA, CONSTANTS.AUTH_ROLE_ENUM.SECRETARIAT]
  },
  name: 'The MITRE Corporation',
  policies: {
    id_quota: 1000
  },
  short_name: 'mitre'
}

const owningOrg = {
  UUID: '88c02595-c8f7-4864-a0e7-e09b3e1da691',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA]
  },
  name: 'Cisco',
  policies: {
    id_quota: 5
  },
  short_name: 'cisco'
}

const existentOrgDummy = {
  UUID: 'ec7fc4ef-a63e-4ac9-b0f4-ac3e57725b4e',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA, CONSTANTS.AUTH_ROLE_ENUM.ADP]
  },
  name: 'Google',
  policies: {
    id_quota: 10
  },
  short_name: 'google'
}

const existentOrgDummy2 = {
  UUID: 'eckuc4ef-a63e-89c9-b0f4-ac3erhf5v5be',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.ROOT_CNA, CONSTANTS.AUTH_ROLE_ENUM.SECRETARIAT]
  },
  name: 'Oracle',
  policies: {
    id_quota: 15
  },
  short_name: 'oracle'
}

const nonExistentOrg = {
  UUID: '794715e2-ded9-4a16-8dfd-9a062a63e1d5',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA]
  },
  name: 'The Oval Office',
  policies: {
    id_quota: 1000
  },
  short_name: 'oval'
}

const toBeDeactivatedOrg = {
  UUID: '345715e2-ded9-4a16-8dfd-9a062a63e1d5',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA]
  },
  name: 'OffOn',
  policies: {
    id_quota: 50
  },
  short_name: 'offon'
}

const toBeActivatedOrg = {
  UUID: '543715e2-ded9-4a16-8dfd-9a062a63e1d5',
  authority: {
    active_roles: []
  },
  name: 'OnOff',
  policies: {
    id_quota: 75
  },
  short_name: 'OnOff'
}

// For validating policies.id_quota below minimum
const orgWithNegativeIdQuota = {
  UUID: '0zoiz5ht-meym-9pj7-95de-ub4ge22rfazn',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA]
  },
  name: 'Stark Industries',
  policies: {
    id_quota: -1
  },
  short_name: 'stark'
}

// For validating policies.id_quota above maximum
const orgExceedingMaxIdQuota = {
  UUID: '0zoir4ht-meym-90j7-95de-ub4ge77rfaz8n',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA]
  },
  name: 'E.E.A.',
  policies: {
    id_quota: 100500
  },
  short_name: 'eea'
}

const orgWithZeroIdQuota = {
  UUID: 'eq3ecuob-yqbf-eheo-piaq-j9zfna86agw4',
  authority: {
    active_roles: [CONSTANTS.AUTH_ROLE_ENUM.CNA]
  },
  name: 'Wayne Enterprises',
  policies: {
    id_quota: 0
  },
  short_name: 'wayne'
}

const existentUser = {
  UUID: 'e13186d5-ce3d-4fd9-aecd-8698c26897f2',
  org_UUID: existentOrg.UUID,
  name: {
    first: 'Cristina',
    last: 'Padro'
  },
  authority: {
    active_roles: []
  },
  secret: '$argon2i$v=19$m=4096,t=3,p=1$+qGHEfH5h4/tk404iWBxFw$xV96/b4NvQVvlZIq57wTS8s7gfKzsfMXRiOyf3ffgcw',
  username: 'cpadro',
  active: true
}

const existentUserDummy = {
  UUID: 'e13556d5-ce3d-4fd9-aecd-8698c26898g5',
  org_UUID: owningOrg.UUID,
  name: {
    first: 'Luis',
    last: 'Ramirez'
  },
  authority: {
    active_roles: []
  },
  secret: '$argon2i$v=19$m=4096,t=3,p=1$yHw6o9QK1Fe3Zn/bzCMejw$A44O4TueJT12iKu1NlhZpIoTYPIOV5KERoJiwAWUPYk',
  username: 'lramirez',
  active: true
}

const existentUserDummy2 = {
  UUID: 'e13gfvh6d5-783d-4fd9-a90d-869yjvjgk8g5',
  org_UUID: existentOrgDummy2.UUID,
  name: {
    first: 'Jose',
    last: 'Alamo',
    middle: 'Natalicio',
    suffix: 'Jr.'
  },
  authority: {
    active_roles: []
  },
  secret: '$argon2i$v=19$m=4096,t=3,p=1$QAwCe7bO5FYsroeiAM+FWw$f3nJRqhYxScf+2eBfBOu18OkIlexFsgOVJW/++8n9l0',
  username: 'natalm',
  active: false
}

const nonExistentUser = {
  UUID: '7d277951-53cb-45c5-82a0-9f1f9c8d29c7',
  org_UUID: existentOrg.UUID,
  name: {
    first: 'David',
    last: 'Smith',
    suffix: 'Sr.'
  },
  authority: {
    active_roles: []
  },
  secret: '$argon2i$v=19$m=4096,t=3,p=1$HQuqVd6W5rxX0VvXtI178Q$kPKWWjIq1czpJFfYZBvpq04SupCfAR/dReDQvgVS+P0',
  username: 'dsmith',
  active: false
}

const userA = {
  username: 'abaker',
  active: true,
  name: {
    first: 'Ashley',
    last: 'Baker',
    middle: 'N',
    suffix: 'I'
  },
  authority: {
    active_roles: []
  },
  org_UUID: existentOrgDummy.UUID,
  UUID: '33394284-4acf-424f-b199-9e57656ee451',
  secret: '$argon2i$v=19$m=4096,t=3,p=1$meXeqZas6Ba2eQrIb3xbiA$x8KRFqYVuvlvsyMiUA2/hSaFbd2mxaKhEM5rXUfx9sw'
}

const userB = { // same username as userA but different org_UUID
  username: 'abaker',
  active: true,
  name: {
    first: 'Ashley',
    last: 'Baker',
    middle: 'N',
    suffix: 'I'
  },
  authority: {
    active_roles: []
  },
  org_UUID: owningOrg.UUID,
  UUID: '33394284-4acf-424f-b199-9e57656ff451',
  secret: '$argon2i$v=19$m=4096,t=3,p=1$meXeqZas6Ba2eQrIb3xbiA$x8KRFqYVuvlvsyMiUA2/hSaFbd2mxaKhEM5rXUfx9sw'
}

const userC = { // same org_UUID as userA but different username
  username: 'wbalck',
  active: true,
  name: {
    first: 'William',
    last: 'Black'
  },
  authority: {
    active_roles: []
  },
  org_UUID: existentOrgDummy.UUID,
  UUID: '33394284-4acf-423b-b199-9e57656ee451',
  secret: '$argon2i$v=19$m=4096,t=3,p=1$meXeqZas6Ba2eQrIb3xbiA$x8KRFqYVuvlvsyMiUA2/hSaFbd2mxaKhEM5rXUfx9sw'
}

const userD = { // same org_UUID as userA but org admin
  username: 'gsmith',
  active: true,
  name: {
    first: 'Gregory',
    last: 'Smith'
  },
  authority: {
    active_roles: [CONSTANTS.USER_ROLE_ENUM.ADMIN]
  },
  org_UUID: existentOrgDummy.UUID,
  UUID: '33394284-4acf-423b-b199-9e57656ee451',
  secret: '$argon2i$v=19$m=4096,t=3,p=1$meXeqZas6Ba2eQrIb3xbiA$x8KRFqYVuvlvsyMiUA2/hSaFbd2mxaKhEM5rXUfx9sw'
}

const allOrgs = [existentOrg, owningOrg, existentOrgDummy, existentOrgDummy2, toBeDeactivatedOrg, toBeActivatedOrg, orgWithNegativeIdQuota, orgExceedingMaxIdQuota, orgWithZeroIdQuota]

const allOwningOrgUsers = [
  existentUserDummy,
  {
    org_UUID: owningOrg.UUID,
    username: 'travispost',
    UUID: '48e89261-5797-4614-81ae-4bf0595b0689',
    active: true,
    name: {
      first: 'Travis',
      last: 'Post',
      middle: 'A.'
    },
    authority: {
      active_roles: []
    },
    secret: '$argon2i$v=19$m=4096,t=3,p=1$+oG246Lm4fOnSTFJZdAfPA$PQIHmY1LgzJn0IYSTlaNqGr00K9f2F0uZQgboQnqRjw'
  },
  {
    org_UUID: owningOrg.UUID,
    username: 'duaspade',
    UUID: 'cd35c708-c6c9-4c52-89e3-c053c2b8cbf5',
    active: true,
    name: {
      first: 'Dua',
      last: 'Spade'
    },
    authority: {
      active_roles: []
    },
    secret: '$argon2i$v=19$m=4096,t=3,p=1$VHsBUuc2pGTYL9seHOJ8Vw$hQXRlzUIJklxYhRoMmwSNScyulMdR4IGmxxyALe6jsw'
  },
  {
    org_UUID: owningOrg.UUID,
    username: 'colewhite',
    UUID: '9624d11f-28c5-4717-8039-3752bf9b03e0',
    active: true,
    name: {
      first: 'Cole',
      last: 'White',
      suffix: 'IV'
    },
    authority: {
      active_roles: []
    },
    secret: '$argon2i$v=19$m=4096,t=3,p=1$NDA1tIslsvipxuOI8raZZQ$FJk57PhH2C+h/L4snN5gRqRsPF2VNHO1Wm+pLo+ACqo'
  },
  {
    org_UUID: owningOrg.UUID,
    username: 'adamlux',
    UUID: '8a6ecd6a-7f7e-48c1-b0d6-8691a388eb66',
    active: true,
    name: {
      first: 'Adam',
      last: 'Lux'
    },
    authority: {
      active_roles: []
    },
    secret: '$argon2i$v=19$m=4096,t=3,p=1$QY6juc/rjf1XOUpIjRJ1/w$KyDUmzLRHymH0HXO70/pgUrkkLTJ4EUs508b517ama4'
  }
]

module.exports = {
  userA,
  userB,
  userC,
  userD,
  allOrgs,
  allOwningOrgUsers,
  secretariatHeader,
  owningOrgHeader,
  userAHeader,
  userDHeader,
  orgHeader,
  owningOrg,
  existentOrg,
  existentOrgDummy,
  existentUserDummy2,
  nonExistentOrg,
  existentUser,
  existentUserDummy,
  existentOrgDummy2,
  nonExistentUser,
  orgWithNegativeIdQuota,
  orgExceedingMaxIdQuota,
  orgWithZeroIdQuota,
  toBeDeactivatedOrg,
  toBeActivatedOrg
}


text:
const sinon = require('sinon')
const chai = require('chai')
const expect = chai.expect
const { faker } = require('@faker-js/faker')

const { USER_CREATE_SINGLE } = require('../../../src/controller/org.controller/org.controller')

const UserRepository = require('../../../src/repositories/userRepository')
const OrgRepository = require('../../../src/repositories/orgRepository')

const stubOrgUUID = faker.datatype.uuid()

const stubOrg = {
  short_name: 'stubOrg',
  name: 'test_user',
  UUID: stubOrgUUID,
  authority: {
    active_roles: ['ADMIN', 'CNA']
  }
}

const stubUser = {
  username: 'stubUser',
  org_UUID: stubOrgUUID,
  UUID: faker.datatype.uuid()
}

describe('Testing the POST /org/:shortname/user endpoint in Org Controller', () => {
  let status, json, res, next, orgRepo, getOrgRepository, getUserRepository, userRepo, req, getOrg

  beforeEach(() => {
    status = sinon.stub()
    json = sinon.spy()
    res = { json, status }
    next = sinon.spy()
    status.returns(res)

    userRepo = new UserRepository()
    getUserRepository = sinon.stub()
    getUserRepository.returns(userRepo)

    orgRepo = new OrgRepository()
    getOrgRepository = sinon.stub()
    getOrgRepository.returns(orgRepo)
    // May have to replace this based on tests
    getOrg = sinon.stub(orgRepo, 'getOrgUUID').returns(stubOrgUUID)
    sinon.stub(userRepo, 'findUsersByOrgUUID').returns(1)
    sinon.stub(orgRepo, 'isSecretariatUUID').returns(false)
    sinon.stub(userRepo, 'isAdminUUID').returns(true)
    sinon.stub(userRepo, 'findOneByUserNameAndOrgUUID').returns(null)
    sinon.stub(userRepo, 'updateByUserNameAndOrgUUID').returns(true)
    sinon.stub(userRepo, 'aggregate').returns([stubUser])
    sinon.stub(userRepo, 'getUserUUID').returns(stubUser.UUID)

    req = {
      ctx: {
        org: stubOrg.short_name,
        uuid: stubOrg.UUID,
        params: {

        },
        repositories: {
          getOrgRepository,
          getUserRepository
        },
        body: {
          stubUser
        }
      }
    }
  })
  context('Positive Tests', () => {
    it('User is created', async () => {
      await USER_CREATE_SINGLE(req, res, next)
      expect(status.args[0][0]).to.equal(200)
      expect(res.json.args[0][0].message).contains('was successfully created')
    })
  })
  context('Negitive tests', () => {
    it('User Fails to be created because not in the same org', async () => {
      req.ctx.org = 'FakeShortName'
      getOrg.withArgs('FakeShortName').returns('FAKEUUID')
      await USER_CREATE_SINGLE(req, res, next)
      expect(status.args[0][0]).to.equal(403)
      expect(res.json.args[0][0].error).contains('NOT_ORG_ADMIN_OR_SECRETARIAT')
    })
  })
})


text:
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 errors = require('../../../src/controller/org.controller/error')
const error = new errors.OrgControllerError()

const userFixtures = require('./mockObjects.user')
const orgController = require('../../../src/controller/org.controller/org.controller')
const orgParams = require('../../../src/controller/org.controller/org.middleware')

class OrgUserSecretResetNotSecretariat {
  async isSecretariat () {
    return false
  }

  async getOrgUUID (shortname) {
    if (shortname === userFixtures.existentOrgDummy.short_name) {
      return userFixtures.existentOrgDummy.UUID
    }

    return userFixtures.owningOrg.UUID
  }
}

class UserSecretResetNotAdmin {
  async updateByUserNameAndOrgUUID () {
    return { n: 1, nModified: 1, ok: 1 }
  }

  async getUserUUID () {
    return null
  }

  async isAdmin () {
    return false
  }

  async findOneByUserNameAndOrgUUID () {
    return userFixtures.userC
  }
}

class UserSecretReset {
  async updateByUserNameAndOrgUUID () {
    return { n: 1, nModified: 1, ok: 1 }
  }

  async getUserUUID (userName, orgUUID) {
    if (userName === userFixtures.userC.username && orgUUID === userFixtures.userC.org_UUID) {
      return userFixtures.userC.UUID
    } else if (userName === userFixtures.userB.username && orgUUID === userFixtures.userB.org_UUID) {
      return userFixtures.userB.UUID
    }

    return userFixtures.userA.UUID
  }

  async isAdmin (username, shortname) {
    if (username === userFixtures.userD.username && shortname === userFixtures.existentOrgDummy.short_name) {
      return true
    } else if (username === userFixtures.userA.username && shortname === userFixtures.existentOrgDummy.short_name) {
      return true
    }

    return false
  }

  async findOneByUserNameAndOrgUUID (username, orgUUID) {
    if (username === userFixtures.userC.username && orgUUID === userFixtures.userC.org_UUID) {
      return userFixtures.userC
    } else if (username === userFixtures.userB.username && orgUUID === userFixtures.userB.org_UUID) {
      return userFixtures.userB
    }

    return userFixtures.userA
  }
}

class UserGetUser {
  async aggregate (aggregation) {
    if (aggregation[0].$match.username === userFixtures.existentUser.username &&
      aggregation[0].$match.org_UUID === userFixtures.existentUser.org_UUID) {
      return [userFixtures.existentUser]
    } else if (aggregation[0].$match.username === userFixtures.existentUserDummy.username &&
      aggregation[0].$match.org_UUID === userFixtures.existentUserDummy.org_UUID) {
      return [userFixtures.existentUserDummy]
    }

    return []
  }
}

class OrgGetUser {
  async isSecretariat (shortname) {
    return shortname === userFixtures.existentOrg.short_name
  }

  async getOrgUUID (shortname) {
    if (shortname === userFixtures.existentOrg.short_name) {
      return userFixtures.existentOrg.UUID
    } else if (shortname === userFixtures.owningOrg.short_name) {
      return userFixtures.owningOrg.UUID
    }

    return null
  }
}

describe('Testing the PUT /org/:shortname/user/:username/reset_secret endpoint in Org Controller', () => {
  context('Negative Tests', () => {
    it('User secret is not reset because org does not exists', (done) => {
      class OrgUserSecretNotResetOrgDoesntExist {
        async isSecretariat () {
          return true
        }

        async getOrgUUID () {
          return null
        }
      }

      class NullUserRepo {
        async getUserUUID () {
          return null
        }

        async findOneByUserNameAndOrgUUID () {
          return null
        }

        async isAdmin () {
          return null
        }
      }

      app.route('/user-secret-not-reset-org-doesnt-exist/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretNotResetOrgDoesntExist() },
            getUserRepository: () => { return new NullUserRepo() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-not-reset-org-doesnt-exist/${userFixtures.nonExistentOrg.short_name}/${userFixtures.existentUser.username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.orgDnePathParam(userFixtures.nonExistentOrg.short_name)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('User secret is not reset because user does not exists', (done) => {
      class OrgUserSecretNotResetUserDoesntExist {
        async isSecretariat () {
          return true
        }

        async getOrgUUID () {
          return userFixtures.existentOrg.UUID
        }
      }

      class UserSecretNotResetUserDoesntExist {
        async updateByUserNameAndOrgUUID () {
          return { n: 0, nModified: 0, ok: 1 }
        }

        async isAdmin () {
          return false
        }

        async findOneByUserNameAndOrgUUID () {
          return null
        }
      }

      app.route('/user-secret-not-reset-user-doesnt-exist/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretNotResetUserDoesntExist() },
            getUserRepository: () => { return new UserSecretNotResetUserDoesntExist() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-not-reset-user-doesnt-exist/${userFixtures.existentOrg.short_name}/${userFixtures.nonExistentUser.username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.userDne(userFixtures.nonExistentUser.username)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    // requester is not the same user (same org but different username)
    it('Requester is from same org but has different username: User secret is not reset because requester is not the same user or is the secretariat or org admin', (done) => {
      app.route('/user-secret-reset-sameOrg/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretResetNotSecretariat() },
            getUserRepository: () => { return new UserSecretResetNotAdmin() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-reset-sameOrg/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userC.username}`) // requester has same org as user but different username
        .set(userFixtures.userAHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

    // requester is not the same user (same username but different org)
    it('Requester has same username but is from different org: User secret is not reset because requester is not the same user or is the secretariat or org admin', (done) => {
      app.route('/user-secret-reset-sameUsername/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretResetNotSecretariat() },
            getUserRepository: () => { return new UserSecretReset() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-reset-sameUsername/${userFixtures.owningOrg.short_name}/${userFixtures.userB.username}`) // requester has same username as user but different org
        .set(userFixtures.userAHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

    // requester is admin but does not belong to the same user's org
    it('Secret is not reset because requester is org admin but does not belong to the same org', (done) => {
      app.route('/user-secret-not-reset-userIsOrgAdminForDifferentOrg/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretResetNotSecretariat() },
            getUserRepository: () => { return new UserSecretReset() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-not-reset-userIsOrgAdminForDifferentOrg/${userFixtures.owningOrg.short_name}/${userFixtures.userB.username}`)
        .set(userFixtures.userDHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

    // requester is not a secretariat or an admin
    it('Secret is not reset because requester is not the user, a secretariat or an admin', (done) => {
      app.route('/user-secret-not-reset-userIsNotUserAdminOrSecretariat/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretResetNotSecretariat() },
            getUserRepository: () => { return new UserSecretResetNotAdmin() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-not-reset-userIsNotUserAdminOrSecretariat/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userC.username}`)
        .set(userFixtures.owningOrgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

  context('Positive Tests', () => {
    let secret
    it('Secret is reset because requester is the user', (done) => {
      app.route('/user-secret-reset-notSameOrgOrSecretariat/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretResetNotSecretariat() },
            getUserRepository: () => { return new UserSecretReset() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-reset-notSameOrgOrSecretariat/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userA.username}`)
        .set(userFixtures.userAHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('API-secret').and.to.be.a('string')
          done()
        })
    })

    it('Secret is reset because requester is a secretariat', (done) => {
      class OrgUserSecretReset {
        async isSecretariat () {
          return true
        }

        async getOrgUUID () {
          return userFixtures.existentOrg.UUID
        }
      }

      app.route('/user-secret-reset-secretariat/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretReset() },
            getUserRepository: () => { return new UserSecretReset() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      chai.request(app)
        .put(`/user-secret-reset-secretariat/${userFixtures.existentOrg.short_name}/${userFixtures.existentUser.username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('API-secret').and.to.be.a('string')
          done()
        })
    })

    it('Secret is reset because requester is an admin that belongs to the same org', (done) => {
      app.route('/user-secret-reset-userIsOrgAdmin/:shortname/:username')
        .put((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgUserSecretResetNotSecretariat() },
            getUserRepository: () => { return new UserSecretReset() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parsePostParams, orgController.USER_RESET_SECRET)

      const CONSTANTS = getConstants()
      userFixtures.userA.authority.active_roles = [CONSTANTS.USER_ROLE_ENUM.ADMIN]

      chai.request(app)
        .put(`/user-secret-reset-userIsOrgAdmin/${userFixtures.existentOrgDummy.short_name}/${userFixtures.userC.username}`)
        .set(userFixtures.userAHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('API-secret').and.to.be.a('string')
          secret = res.body['API-secret']
          userFixtures.userA.authority.active_roles = []
          done()
        })
    })

    it('Admin user role preserved after resetting secret', (done) => {
      app.route('/user-get-user/:shortname/:username')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new OrgGetUser() },
            getUserRepository: () => { return new UserGetUser() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_SINGLE)

      userFixtures.existentUser.secret = secret

      chai.request(app)
        .get(`/user-get-user/${userFixtures.existentOrg.short_name}/${userFixtures.existentUser.username}`)
        .set(userFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('username').and.to.equal(userFixtures.existentUser.username)
          expect(res.body).to.have.property('org_UUID').and.to.equal(userFixtures.existentUser.org_UUID)
          done()
        })
    })
  })
})


text:
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 errors = require('../../../src/controller/org.controller/error')
const error = new errors.OrgControllerError()

const orgFixtures = require('./mockObjects.user')
const orgController = require('../../../src/controller/org.controller/org.controller')
const orgParams = require('../../../src/controller/org.controller/org.middleware')

describe('Testing the GET /org/:shortname/users endpoint in Org Controller', () => {
  context('Negative Tests', () => {
    it('should return 404 not found because org does not exist', (done) => {
      class NoOrg {
        async getOrgUUID () {
          return null
        }

        async isSecretariat () {
          return false
        }
      }

      class Blank {
        async aggregate () {
          return []
        }
      }

      app.route('/org-does-not-exist/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new NoOrg() },
            getUserRepository: () => { return new Blank() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      chai.request(app)
        .get(`/org-does-not-exist/${orgFixtures.nonExistentOrg.short_name}/users`)
        .set(orgFixtures.owningOrgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(404)
          expect(res).to.have.property('body').and.to.be.a('object')
          const errObj = error.orgDnePathParam(orgFixtures.nonExistentOrg.short_name)
          expect(res.body.error).to.equal(errObj.error)
          expect(res.body.message).to.equal(errObj.message)
          done()
        })
    })

    it('should return 403 forbidden because requester does not belong to the same org', (done) => {
      class NotSameOrg {
        async getOrgUUID () {
          return 'not-an-org'
        }

        async isSecretariat () {
          return false
        }
      }

      class Blank {
        async aggregate () {
          return []
        }
      }

      app.route('/requester-does-not-belong/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new NotSameOrg() },
            getUserRepository: () => { return new Blank() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      chai.request(app)
        .get(`/requester-does-not-belong/${orgFixtures.owningOrg.short_name}/users`)
        .set(orgFixtures.orgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

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

  context('Positive Tests', () => {
    it('should list the users for cisco org because requester belongs to the same org', (done) => {
      class GetOrgUUID {
        async getOrgUUID () {
          return orgFixtures.owningOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class GetAllOrgUsers {
        async aggregatePaginate () {
          const res = {
            itemsList: [orgFixtures.existentUserDummy],
            itemCount: 1,
            itemsPerPage: 1000,
            currentPage: 1,
            pageCount: 1,
            pagingCounter: 1,
            hasPrevPage: false,
            hasNextPage: false,
            prevPage: null,
            nextPage: null
          }
          return res
        }
      }

      app.route('/user-list-returned-same-org/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new GetOrgUUID() },
            getUserRepository: () => { return new GetAllOrgUsers() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      chai.request(app)
        .get(`/user-list-returned-same-org/${orgFixtures.owningOrg.short_name}/users`)
        .set(orgFixtures.owningOrgHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('users').and.to.be.a('array').and.to.have.lengthOf(1)
          expect(res.body.users[0]).to.have.property('org_UUID').and.to.equal(orgFixtures.owningOrg.UUID)
          done()
        })
    })

    it('should list the users for cisco org because requester is the secretariat', (done) => {
      class GetOrgUUID {
        async getOrgUUID () {
          return orgFixtures.owningOrg.UUID
        }

        async isSecretariat () {
          return true
        }
      }

      class GetAllOrgUsers {
        async aggregatePaginate () {
          const res = {
            itemsList: [orgFixtures.existentUserDummy],
            itemCount: 1,
            itemsPerPage: 1000,
            currentPage: 1,
            pageCount: 1,
            pagingCounter: 1,
            hasPrevPage: false,
            hasNextPage: false,
            prevPage: null,
            nextPage: null
          }
          return res
        }
      }

      app.route('/user-list-returned-secretariat/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new GetOrgUUID() },
            getUserRepository: () => { return new GetAllOrgUsers() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      chai.request(app)
        .get(`/user-list-returned-secretariat/${orgFixtures.owningOrg.short_name}/users`)
        .set(orgFixtures.secretariatHeader)
        .end((err, res) => {
          if (err) {
            done(err)
          }

          expect(res).to.have.status(200)
          expect(res).to.have.property('body').and.to.be.a('object')
          expect(res.body).to.have.property('users').and.to.be.a('array').and.to.have.lengthOf(1)
          expect(res.body.users[0]).to.have.property('org_UUID').and.to.equal(orgFixtures.owningOrg.UUID)
          done()
        })
    })

    it('Page query param not provided: should list non-paginated users because users fit in one page', async () => {
      class GetOrgUUID {
        async getOrgUUID () {
          return orgFixtures.owningOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class GetAllOrgUsers {
        async aggregatePaginate () {
          const res = {
            itemsList: orgFixtures.allOwningOrgUsers,
            itemCount: orgFixtures.allOwningOrgUsers.length,
            itemsPerPage: 500,
            currentPage: 1,
            pageCount: 1,
            pagingCounter: 1,
            hasPrevPage: false,
            hasNextPage: false,
            prevPage: null,
            nextPage: null
          }
          return res
        }
      }

      app.route('/user-list-returned-not-secretariat-limit-default/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new GetOrgUUID() },
            getUserRepository: () => { return new GetAllOrgUsers() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      const testOwningOrgHeader = Object.assign({}, orgFixtures.owningOrgHeader)
      const res = await chai.request(app)
        .get(`/user-list-returned-not-secretariat-limit-default/${orgFixtures.owningOrg.short_name}/users`)
        .set(testOwningOrgHeader)

      expect(res).to.have.status(200)
      expect(res).to.have.property('body').and.to.be.a('object')
      expect(res.body).to.have.property('users').and.to.be.a('array').and.to.have.lengthOf(orgFixtures.allOwningOrgUsers.length)
      expect(res.body).to.not.have.property('totalCount')
      expect(res.body).to.not.have.property('itemsPerPage')
      expect(res.body).to.not.have.property('pageCount')
      expect(res.body).to.not.have.property('currentPage')
      expect(res.body).to.not.have.property('prevPage')
      expect(res.body).to.not.have.property('nextPage')
    })

    it('Page query param not provided: should list the users for cisco org in two pages (page 1/2)', async () => {
      const itemsPerPage = 3

      class GetOrgUUID {
        async getOrgUUID () {
          return orgFixtures.owningOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class GetAllOrgUsers {
        async aggregatePaginate () {
          const res = {
            itemsList: [orgFixtures.allOwningOrgUsers[0], orgFixtures.allOwningOrgUsers[1], orgFixtures.allOwningOrgUsers[2]],
            itemCount: orgFixtures.allOwningOrgUsers.length,
            itemsPerPage: itemsPerPage,
            currentPage: 1,
            pageCount: 2,
            pagingCounter: 1,
            hasPrevPage: false,
            hasNextPage: true,
            prevPage: null,
            nextPage: 2
          }
          return res
        }
      }

      app.route('/user-list-returned-not-secretariat-limit-3-1/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new GetOrgUUID() },
            getUserRepository: () => { return new GetAllOrgUsers() }
          }
          req.ctx.repositories = factory
          // temporary fix for #920: force pagnation
          req.TEST_PAGINATOR_LIMIT = itemsPerPage
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      const testOwningOrgHeader = Object.assign({}, orgFixtures.owningOrgHeader)
      const res = await chai.request(app)
        .get(`/user-list-returned-not-secretariat-limit-3-1/${orgFixtures.owningOrg.short_name}/users`)
        .set(testOwningOrgHeader)

      expect(res).to.have.status(200)
      expect(res).to.have.property('body').and.to.be.a('object')
      expect(res.body).to.have.property('users').and.to.be.a('array').and.to.have.lengthOf(3)
      expect(res.body).to.have.property('totalCount').and.to.equal(orgFixtures.allOwningOrgUsers.length)
      expect(res.body).to.have.property('itemsPerPage').and.to.equal(itemsPerPage)
      expect(res.body).to.have.property('pageCount').and.to.equal(2)
      expect(res.body).to.have.property('currentPage').and.to.equal(1)
      expect(res.body).to.have.property('prevPage').and.to.equal(null)
      expect(res.body).to.have.property('nextPage').and.to.equal(2)
    })

    it('Page query param provided: should list the users for cisco org in two pages (page 2/2)', async () => {
      class GetOrgUUID {
        async getOrgUUID () {
          return orgFixtures.owningOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class GetAllOrgUsers {
        async aggregatePaginate () {
          const res = {
            itemsList: [orgFixtures.allOwningOrgUsers[3], orgFixtures.allOwningOrgUsers[4]],
            itemCount: orgFixtures.allOwningOrgUsers.length,
            itemsPerPage: 3,
            currentPage: 2,
            pageCount: 2,
            pagingCounter: 1,
            hasPrevPage: true,
            hasNextPage: false,
            prevPage: 1,
            nextPage: null
          }
          return res
        }
      }

      app.route('/user-list-returned-not-secretariat-limit-3-2/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new GetOrgUUID() },
            getUserRepository: () => { return new GetAllOrgUsers() }
          }
          req.ctx.repositories = factory
          // temporary fix for #920: force pagnation
          req.TEST_PAGINATOR_LIMIT = 3
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      const testOwningOrgHeader = Object.assign({}, orgFixtures.owningOrgHeader)
      const res = await chai.request(app)
        .get(`/user-list-returned-not-secretariat-limit-3-2/${orgFixtures.owningOrg.short_name}/users?page=2`)
        .set(testOwningOrgHeader)

      expect(res).to.have.status(200)
      expect(res).to.have.property('body').and.to.be.a('object')
      expect(res.body).to.have.property('users').and.to.be.a('array').and.to.have.lengthOf(2)
      expect(res.body).to.have.property('totalCount').and.to.equal(orgFixtures.allOwningOrgUsers.length)
      expect(res.body).to.have.property('itemsPerPage').and.to.equal(3)
      expect(res.body).to.have.property('pageCount').and.to.equal(2)
      expect(res.body).to.have.property('currentPage').and.to.equal(2)
      expect(res.body).to.have.property('prevPage').and.to.equal(1)
      expect(res.body).to.have.property('nextPage').and.to.equal(null)
    })

    it('Page query param provided: should return an empty list because no user exist for stark org', async () => {
      class GetOrgUUID {
        async getOrgUUID () {
          return orgFixtures.owningOrg.UUID
        }

        async isSecretariat () {
          return false
        }
      }

      class GetAllOrgUsers {
        async aggregatePaginate () {
          const res = {
            itemsList: [],
            itemCount: 0,
            itemsPerPage: 500,
            currentPage: 1,
            pageCount: 1,
            pagingCounter: 1,
            hasPrevPage: false,
            hasNextPage: false,
            prevPage: null,
            nextPage: null
          }
          return res
        }
      }

      app.route('/user-list-no-users/:shortname/users')
        .get((req, res, next) => {
          const factory = {
            getOrgRepository: () => { return new GetOrgUUID() },
            getUserRepository: () => { return new GetAllOrgUsers() }
          }
          req.ctx.repositories = factory
          next()
        }, orgParams.parseGetParams, orgController.USER_ALL)

      const testOwningOrgHeader = Object.assign({}, orgFixtures.owningOrgHeader)
      const res = await chai.request(app)
        .get(`/user-list-no-users/${orgFixtures.owningOrg.short_name}/users?page=1`)
        .set(testOwningOrgHeader)

      expect(res).to.have.status(200)
      expect(res).to.have.property('body').and.to.be.a('object')
      expect(res.body).to.have.property('users').and.to.be.a('array').and.to.have.lengthOf(0)
      expect(res.body).to.not.have.property('totalCount')
      expect(res.body).to.not.have.property('itemsPerPage')
      expect(res.body).to.not.have.property('pageCount')
      expect(res.body).to.not.have.property('currentPage')
      expect(res.body).to.not.have.property('prevPage')
      expect(res.body).to.not.have.property('nextPage')
    })
  })
})


text:
const chai = require('chai')
const sinon = require('sinon')
const { faker } = require('@faker-js/faker')
const expect = chai.expect

const OrgRepository = require('../../../src/repositories/orgRepository.js')
const UserRepository = require('../../../src/repositories/userRepository.js')
const { ORG_CREATE_SINGLE } = require('../../../src/controller/org.controller/org.controller.js')

const stubAdpOrg = {
  short_name: 'adpOrg',
  name: 'test_adp',
  authority: {
    active_roles: [
      'ADP'
    ]
  },
  policies: {
    id_quota: 200
  }
}

const stubAdpCnaOrg = {
  short_name: 'cnaAdpOrg',
  name: 'testCnaAdp',
  authority: {
    active_roles: [
      'ADP',
      'CNA'
    ]
  },
  policies: {
    id_quota: 200
  }
}

describe('Testing creating orgs with the ADP role', () => {
  let status, json, res, next, getOrgRepository, orgRepo, getUserRepository,
    userRepo, updateOrg
  beforeEach(() => {
    status = sinon.stub()
    json = sinon.spy()
    res = { json, status }
    next = sinon.spy()
    status.returns(res)

    orgRepo = new OrgRepository()
    getOrgRepository = sinon.stub()
    getOrgRepository.returns(orgRepo)

    userRepo = new UserRepository()
    getUserRepository = sinon.stub()
    getUserRepository.returns(userRepo)

    sinon.stub(orgRepo, 'findOneByShortName').returns(null)
    // Used to get newOrg object
    updateOrg = sinon.stub(orgRepo, 'updateByOrgUUID').returns(true)
    sinon.stub(orgRepo, 'aggregate').returns(true)
    sinon.stub(orgRepo, 'getOrgUUID').returns(true)
    sinon.stub(userRepo, 'getUserUUID').returns(true)
  })
  it('Should return newly created org with id_quota of 0 and ADP role', async () => {
    const req = {
      ctx: {
        uuid: faker.datatype.uuid(),
        repositories: {
          getOrgRepository,
          getUserRepository
        },
        body: {
          ...stubAdpOrg
        }
      }
    }

    await ORG_CREATE_SINGLE(req, res, next)

    expect(status.args[0][0]).to.equal(200)
    expect(updateOrg.args[0][1].policies.id_quota).to.equal(0)
    expect(updateOrg.args[0][1].authority.active_roles[0]).to.equal('ADP')
  })

  it('Should have nonzero id_quota when created with ADP and CNA role', async () => {
    const req = {
      ctx: {
        uuid: faker.datatype.uuid(),
        repositories: {
          getOrgRepository,
          getUserRepository
        },
        body: {
          ...stubAdpCnaOrg
        }
      }
    }

    await ORG_CREATE_SINGLE(req, res, next)

    expect(status.args[0][0]).to.equal(200)
    expect(updateOrg.args[0][1].policies.id_quota).to.equal(200)
    expect(updateOrg.args[0][1].authority.active_roles[0]).to.equal('ADP')
    expect(updateOrg.args[0][1].authority.active_roles[1]).to.equal('CNA')
  })
})