Cómo realizar una simple prueba de integración usando Firebase Auth

ejemplo de codigo

Al querer hacer pruebas de integración a una API que necesita token de usuario de firebase para realizar la autenticación, surge un problema: Se necesita sacar manualmente el token para enviarlo en todas las variables. Aquí veremos cómo automatizar una simple prueba de integración usando Mocha, Chai y Supertest a un servidor basado en Express.

Pre-requisitos:

  • Un proyecto ya creado en Firebase.
  • Node 8.0+

Inicialización de proyecto y paquetes

Dentro de la carpeta del proyecto, iniciamos la consola y ponemos el siguiente comando:

> npm init

Rellenamos los datos y posteriormente vamos a ejecutar dos comandos separados, los cuales son:

> npm install firebase --save-dev
> npm install firebase-admin

Si te preguntas lo siguiente: ¿Por qué no puedo instalar primero firebase-admin que firebase o en una sola línea de código? Instalando “firebase-admin” primero, genera problemas al obtener el SDK de autenticación, por eso es separado para evitar este pequeño error.

Obtener el código de inicialización de Firebase

Para la inicialización del cliente al estar en la página principal del proyecto, seleccionamos la opción de “Añade Firebase a tu aplicación Web”, el cual nos dará un fragmento de código el cual solo necesitaremos la variable de “config”.

const config = {
  apiKey: "<API_KEY>",
  authDomain: "<PROJECT_ID>.firebaseapp.com",
  databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
  storageBucket: "<BUCKET>.appspot.com",
};

Para la parte de administrador, necesitamos generar una clave privada, el cual es un archivo en formato “JSON”, para ello entramos en la configuración del proyecto, después accedemos a Cuentas de Servicio y damos click a “Generar nueva clave privada”. El archivo que descargará lo guardamos en la carpeta del proyecto y lo renombramos a “firebase.json”. Dentro de la misma página, vamos a guardar el valor de la propiedad “databaseURL”.

Creando la función para obtener token

Vamos a crear un archivo llamado “token.js” en la carpeta raíz del proyecto, el cual importaremos el SDK de autenticación de firebase:

const firebase = require('firebase'); // Firebase
require('firebase/auth'); // SDK de Auth a firebase

Posteriormente, importamos el SDK de administrador de firebase.

const admin = require('firebase-admin');

Una vez importados los paquetes, iniciamos la inicialización del SDK de administrador y cliente con el siguiente código:

const serviceAccount = require('./firebase.json');
 
const clientFire = firebase.initializeApp({
  apiKey: "<API_KEY>",
  authDomain: "<PROJECT_ID>.firebaseapp.com",
  databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
  storageBucket: "<BUCKET>.appspot.com",
});
 
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://ejemplo.firebaseio.com' // Valor de databaseURL
});

Una vez realizado esto, podremos finalmente crear la función que nos genere el token. Creamos una función con exportación:

module.exports = async() => {
  // Creamos un usuario para obtener su UID
  const user = await admin.auth().createUser({
    displayName: 'José José'
  });
  // Crear un token personalizado con el UID
  const tempToken = await admin.auth().createCustomToken(user.uid);    
   // Iniciar sesión con el token anterior
  await clientFire.auth().signInWithCustomToken(tempToken);
  // Esperamos a iniciar sesión y obtenemos los datos
  const token = await clientFire.auth().currentUser.getIdToken();
  return token;
}

Finalmente, el código estaría conformado de la siguiente manera:

const firebase = require('firebase');
require('firebase/auth');
const admin = require('firebase-admin');
 
const serviceAccount = require('./firebase.json');
 
const clientFire = firebase.initializeApp({
  apiKey: "<API_KEY>",
  authDomain: "<PROJECT_ID>.firebaseapp.com",
  databaseURL: "https://<DATABASE_NAME>.firebaseio.com",
  storageBucket: "<BUCKET>.appspot.com",
});
 
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: 'https://ejemplo.firebaseio.com' // Valor de databaseURL
});
 
module.exports = async() => {
  // Creamos un usuario para obtener su UID
  const user = await admin.auth().createUser({
    displayName: 'José José'
  });
  // Crear un token personalizado con el UID
  const tempToken = await admin.auth().createCustomToken(user.uid);
  // Iniciar sesión con el token anterior
  await clientFire.auth().signInWithCustomToken(tempToken);
  // Esperamos a iniciar sesión y obtenemos los datos
  const token = await clientFire.auth().currentUser.getIdToken();
  return token;
}

Creando una simple prueba de integración

Para hacer esto, necesitamos instalar dos librerías: chai y supertest. Para ello, ejecutamos los siguientes comandos:

> npm install –g mocha
> npm install chai supertest --save-dev

Una vez instalados, procederemos a hacer una carpeta llamada “tests”, dentro de ella creamos un archivo llamado “prueba.test.js”, dentro de él, importamos los paquetes de chai y supertest.

const { expect, assert } = require('chai');
const request = require('supertest');

Después agregamos el archivo generador de token:

const token = require('../token');
let tempToken;

Posteriormente, generamos la siguiente prueba de la siguiente forma:

before(async () => {
  tempToken = await token();
  console.log('token', tempToken);
  return tempToken;
});
describe('Prueba básica', () => {
  it('should return status 200', async () => {
    const response = await request('https://dominio.com')
      .post('/ruta')
      .set('x-api-token', token) // Enviamos el token en un header
      .expect(200);
  });
});

Posteriormente, ejecutamos el siguiente comando para iniciar la prueba de integración con un tiempo de espera de 10 segundos.

> mocha --timeout 10000

Lo cual nos debería dar una respuesta como la siguiente:

Prueba básica

√ should return status 200 (457ms)

1 passing (3s)

Con ello, deberíamos obtener el token impreso en consola y enviado al Endpoint de una API en REST.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *