-1

I want to write a test for my passport local auth. If auth is a success or failure in both scenarios the user gets redirected which sends a status 302. Since I can't distinguish between success or failed auth since the status codes are the same, so I decided to write custom methods (which is the not commented section) but when I send the 401 unauthorized status code it doesn't redirect the user it shows a page with a link to the redirect route.

How could you test passport auth using Jest and Supertest?

/*
app.post('/users/login', passport.authenticate('local', {
    successRedirect: '/users/dashboard',
    failureRedirect: '/users/login', 
    failureFlash: true,
}));*/
app.post('/users/login', (req, res, next) => {
  passport.authenticate('local', (err, user, info) => {
    if (err) return next(err);
    if (!user) res.redirect(401, '/users/login'); // failure
    req.logIn(user, (err) => {
      if (err) return next(err); 
      return res.redirect('/users/dashboard'); //success
  });
  })(req, res, next);
});

Here is my Jest/Supertest test: In this case, the test will pass but on the front-end, the user wouldn't get redirected directly to the URL: '/users/dashboard'

    test('should return a status code: 401', async () => {
        const response = await request(app).post('/users/login').send({
            // incorrect login
            email: 'jane@gmail.com',
            password: 'asdfa'
        })
        expect(response.statusCode).toBe(401)
    })
})

Thank you

Edit: expect(response.headers['Location']).toEqual('/users/login'); seems to be what I need but response.headers['Location'] gives me undefined.

Test:

        test('should redirect to /users/login', async () => {
        const response = await request(app).post('/users/login').send({
            email: 'jane@gmail.com',
            password: 'incorrectPassword'
        })
        expect(response.headers['Location']).toEqual('/users/login');
    })

new post route:

app.post('/users/login', passport.authenticate('local', {
successRedirect: '/users/dashboard',
failureRedirect: '/users/login', 
failureFlash: true

}));

NoobSailboat
  • 109
  • 9
  • Well why _would_ the user be redirected on a 401? If that's the behaviour you want, your test is explicitly requiring the wrong thing. – jonrsharpe Jun 08 '22 at 19:10
  • I want to send a 401 so that the test can check if the status code is a 401. I don't want the user to see a 401 error it's just meant for my test. How else can I test if a login was successful or not? – NoobSailboat Jun 08 '22 at 19:14
  • But then, as you say, the user doesn't get redirected, so the behaviour is wrong. It's not at all clear what you're asking - what do you _want_ and _expect_ to happen? If you want a redirect, send a redirect. – jonrsharpe Jun 08 '22 at 19:16
  • I want to test my passport auth. I want to have an automatic test of the success and failure scenarios so when I refactor code I know my auth still works. I looked up on StackOverflow and it seems to me the only way to test something like it is with status codes. – NoobSailboat Jun 08 '22 at 19:21
  • You do have a test. You've carefully written one and made it pass. But apparently that wasn't what you wanted, so **why did you do that?** What _did_ you want, and why didn't you test for that? If you want a redirect, why test for not-a-redirect? – jonrsharpe Jun 08 '22 at 19:22
  • Both a successful login and failed login lead to a redirect so there is no way I know how to distinguish between a successful and failed login that's why I added status codes. I guess status codes are not what I need to test my post route. – NoobSailboat Jun 08 '22 at 19:27
  • They're already different responses, they redirect to _different places_. Changing the status code away from 3xx is certainly _not_ going to help if the redirect behaviour is what you actually want. Review what is different between the requests you _actually want_, e.g. in the network tab, then read the SuperTest docs to see how to assert on that. – jonrsharpe Jun 08 '22 at 19:30

1 Answers1

0

Don't set the status code to 401!

You can expect the Location header like:

expect(response.headers['Location']).toEqual('/users/login');
// or
expect(response.headers['Location']).toContain('/users/login');

More about the Location header at MDN

Amr Elmohamady
  • 156
  • 2
  • 6