Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

superagent / supertest with async / await

Goal is to set the variable auth correctly for further use, hence i want to refactor the function loginUser:

function loginUser(user, request, auth) {
  return function(done) {
    request
      .post('/users/login')
      .send(credentials)
      .expect(200)
      .end(onResponse);

    function onResponse(err, res) {
      auth.token = res.body.token;
      return done();
    }
  };
}


 loginUser(user, request, auth)(function() {
  request.get(testUrl)
    .set('Authorization', `bearer ${auth.token}`)
    .expect(200, done);
});

to use async / await like this (without the callback):

auth = await loginUser(user, request);
request.get(testUrl)
    .set('Authorization', `bearer ${auth.token}`)
    .expect(200, done);

But i am struggling of returning / setting auth correctly (it would not matter if i pass auth as parameter or as return value).

What i tried was stuff like this:

async function loginUser(user, request) {
  let auth;
  await request
    .post('/users/login')
    .send(credentials)
    .expect(200)
    .end(onResponse);

  function onResponse(err, res) {
    auth.token = res.body.token;
  }
  return auth;
}

But auth was never set correctly.

like image 349
Gobliins Avatar asked Jul 20 '18 09:07

Gobliins


2 Answers

Don't use 'end' syntax, that's for callbacks:

const response = await request.post(...)
  .expect(200)
const {body: {token}} = response
return token

Basically it should look like sync code

like image 56
Lev Kuznetsov Avatar answered Nov 05 '22 21:11

Lev Kuznetsov


The problem is that the onResponse method is being executed later than you the return of the function because of the event loop in Nodejs. So you will have to do resolve the promise exactly when you receive the data

The method loginUserInternal could be like this:

function loginUserInternal(user, request) {
  return new Promise((resolve,reject) => {
    let auth = {};
    request
      .post('/users/login')
      .send({
        username: user.username,
        password: user.password_decoded,
      })
      .expect(200)
      .end(onResponse);
    function onResponse(err, res) {
      if(err) return reject(err)
      auth.id = res.body.id;
      auth.token = res.body.token;
      auth.tokenExpires = res.body.tokenExpires;
      resolve(auth)
    }
  })
}

And call it like you were doing with async await.

like image 21
David Viejo Avatar answered Nov 05 '22 21:11

David Viejo