jeudi 12 mars 2020

How to run integration tests in Node.js with Firebase admin

Our back-end (Node) and our front-end (React) are hosted on GCP and Heroku, respectively.

We're working on adding automated tests to our back-end code, but arenot sure how to test authenticated routes, as all our routes are authenticated using Firebase. Specifically, we have Firebase Client on the front-end and Firebase Admin on the backend.

Our test framework currently uses Jest and Supertest. We've tried using the firebase-mock package to test it, but that hasn't really worked. As we always get a 400 response, even when passing a mock token.

Here's the code for our auth middleware:

// This middleware will verify that a request is coming from an authorized user
const admin = require('firebase-admin')

module.exports = async function auth(req, res, next) {
  // Try to extract the firebase-auth-token from the request header, 
  // respond with access denied if firebase-auth-token is not found
  const token = req.header('x-auth-token')
  if (!token) res.status(401).send('Access denied. No auth token provided.')

  try {
    const decodedToken = await admin.auth().verifyIdToken(token)

    req.user = { ...decodedToken }
    next()
  } catch (ex) {
    // Respond with 'bad request' if the token is invalid
    res.status(400).send('Invalid token.')
  }
}

Here's the code for our auth.test.js file:

const request = require('supertest')
const firebasemock = require('firebase-mock')
const server = require('../../index')

const mockauth = new firebasemock.MockAuthentication()

const mocksdk = new firebasemock.MockFirebaseSdk(
  null,
  // use null if your code does not use AUTHENTICATION
  () => mockauth,
  null,
  null,
  null
)

describe('auth middleware', () => {
  afterEach(async () => {
    await server.close()
  })

  let token

  const exec = () =>
    request(server)
      .get('/api/users')
      .set('x-auth-token', token)

  it('should return 200 if token is valid', async () => {
    mocksdk.auth().autoFlush()

    // create a user
    mocksdk.auth().createUser({
      uid: '123',
      email: 'test@test.com',
      password: 'abc123'
    })

    const user = await mocksdk.auth().getUser('123')
    token = await user.getIdToken()

    const res = await exec()

    expect(res.status).toBe(200)
  })
})

Aucun commentaire:

Enregistrer un commentaire