简体   繁体   中英

Bcrypt.compare not executing in chai/mocha tests, but executing in code

I have some node.js backend in my project. To encrypt passwords I using bcrypt . To compare string password from requst with hashed password in DB I usin bcrypt.compare function. My bcrypt.compare function works well in code. I tested it manually with Postman and it runs well in production. But in tests with chai-http and mocha it hangs up.

Test. I use mocha with chai-http to make http POST request:

describe('Testing login', () => {
  it('should return status 200 when there is such user in DB and password is correct', (done) => {
    chai.request(server)
    .post('/login')
    .send({
      login: 'test@test.test',
      password: 'somepassword'
    })
    .end((err, res) => {
      res.should.have.status(200)
      done()
    })
  })
})

Controller bcrypt fucntion looks like that:

async function auth (req, res) {
  let { login, password } = req.body
  try {
    let payload = {}
    let result = {}
    await
    User.findOne({ where: { userEmail: login } }).then(user => {      
      return result = user
    })
    bcrypt.compare(password, result.dataValues.password, await function (err, data) {
      if (err) {        
        throw Error(err)
      }
      if (result && data) {       
        payload.isAdmin = result.dataValues.isAdmin
        payload.ID = result.dataValues.id
        let token = jwt.sign(payload, 'yoursecret')
        res.status(200).send({ token: token })
      } else { res.status(401) }
    })
  } catch (error) {
    res.sendStatus(500)
  }
}

Is there any way to test this function?

Additionnal information
mocha version 5.2.0 - global and local
node v8.11.4
windows 10 x64

"devDependencies": {
  "@types/chai-as-promised": "^7.1.0",
  "chai": "^4.1.2",
  "chai-as-promised": "^7.1.1",
  "chai-http": "^4.2.0",
  "eslint": "^5.5.0",
  "eslint-config-standard": "^12.0.0",
  "eslint-plugin-import": "^2.14.0",
  "eslint-plugin-node": "^7.0.1",
  "eslint-plugin-promise": "^4.0.1",
  "eslint-plugin-standard": "^4.0.0",
  "express-unit": "^2.1.1",
  "mocha": "^5.2.0",
  "mock-express-request": "^0.2.2",
  "mock-express-response": "^0.2.2",
  "nyc": "^13.0.1",
  "proxyquire": "^2.1.0",
  "sinon": "^6.2.0",
  "supertest": "^3.3.0",
  "ws": "3.3.2"
}

I believe there are a few problems, and a few places to look for resources. I do not believe this is a problem with chai-http .

MDN async/await functions
Using bcrypt with Promises.

Here is a rewritten version of your route handler:

 async function auth(req, res) { let { login, password } = req.body try { let payload = {} let result = await User.findOne({ where: { userEmail: login } }); const data = await bcrypt.compare(password, result.dataValues.password); if (result && data) { payload.isAdmin = result.dataValues.isAdmin payload.ID = result.dataValues.id let token = jwt.sign(payload, 'yoursecret') res.status(200).send({ token: token }) } else { res.sendStatus(401) } } catch (error) { res.sendStatus(500) } } 

I'm not sure how you're setting up your routes, but a common mistake is not handling the async functions correctly, as express doesn't do this for you.

Let me know if this helps. It would also be helpful to see how you are initializing routes and the versions of Node, Express, chai-http, bcrypt, and jsonwebtoken you are using.

Wrong behaviour wasn't connected to chai/mocha/bcript. It was caused by following statement

    } else {
        res.status(401)
    }

correct code should be

    } else {
        res.status(401).send(something)
    }

or

    } else {
        res.sendStatus(401)
    }

I think Express waiting for .send() after .status() and keep connection without response

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM