Jest зависает в i18n.configure () - PullRequest
1 голос
/ 01 февраля 2020

Я создаю Restfull API с использованием Node.js и express и решил протестировать мое приложение с использованием Jest и Supertest , в моем классе приложений мне требуется некоторая конфигурация i18n (i18n - это библиотека, используемая для переводов).

При работе на обычном сервере express и тестировании моих маршрутов вручную с помощью Бессонница или Почтальон , все отлично работает. Но когда я пытаюсь создать тест для маршрута / login , тест выполняется нормально, и я получаю ожидаемые результаты, но Jest никогда не завершает работу и выдает Jest has detected the following 1 open handle potentially keeping Jest from exiting. Из того, что он указывает, кажется, что вызов be i18n.configure(... оставляет открытый дескриптор, как ни странно, я проверил метод configure, и он не асинхронный.

Вот вывод консоли: enter image description here

Вот мое приложение. js Файл:

require("dotenv").config({
  path: process.env.NODE_ENV === "test" ? ".env.test" : ".env"
});
const express = require("express");
const cookieParser = require("cookie-parser");

class AppController {
  constructor() {
    this.express = express();
    this.configure();
    this.middlewares();
    this.routes();
  }

  async configure() {
    this.i18n = require("./config/i18n");
  }

  middlewares() {
    this.express.use(express.json());
    this.express.use(cookieParser());
    this.express.use(this.i18n.init);
  }

  routes() {
    this.express.use(require("./routes"));
  }
}

module.exports = new AppController().express;

Файл конфигурации i18n:

const i18n = require("i18n");

i18n.configure({
  locales: ["pt-br", "en-us"],
  defaultLocale: "pt-br",
  cookie: "locale",
  directory: "./locales",
  autoReload: true
});
i18n.setLocale("pt-br");

module.exports = i18n;

Тест сам по себе:

const request = require("supertest");    
const app = require("../../src/app.js");

describe("Authentication", () => {

  it("should not authenticate when user does not exist", async () => {
    const response = await request(app)
      .post("/login")
      .send({
        username: "john",
        password: "123123"
      });

    expect(response.status).toBe(401);
  });
});

Маршрут / login ( Он находится внутри папки входа, поэтому я могу объявить только "/" для маршрута ):

const routes = require("express").Router();

const LoginController = require("../app/controllers/LoginController");

routes.post("/", LoginController.index);

module.exports = routes;

LoginController с индексной функцией:

const passport = require("../../app/middlewares/passport");
const jwt = require("jsonwebtoken");

class LoginController {
  async index(req, res) {
    passport.authenticate("local", { session: false }, (error, user) => {
      if (error || !user) {
        res.status(401).send(res.__(error));
      } else {
        const payload = {
          username: user.username,
          expires: Date.now() + parseInt(process.env.JWT_EXPIRATION_MS)
        };

        req.login(payload, { session: false }, error => {
          if (error) {
            res.status(400).send({ error });
          }

          const token = jwt.sign(
            JSON.stringify(payload),
            process.env.APP_SECRET
          );

          res.cookie("jwt", token, { httpOnly: true, secure: true });
          res.status(200).send({ username: user.username });
        });
      }
    })(req, res);
  }
}

module.exports = new LoginController();

На всякий случай вот паспорт стратегии:

const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const passportJWT = require("passport-jwt");
const JWTStrategy = passportJWT.Strategy;

const { User } = require("../models");

passport.use(
  new LocalStrategy(async (username, password, done) => {
    try {
      const user = await User.findOne({ where: { username } });
      let passwordsMatch = false;
      if (user) {
        passwordsMatch = await user.checkPassword(password);
      }

      if (passwordsMatch) {
        return done(null, user);
      } else {
        return done("Incorrect username and/or password");
      }
    } catch (error) {
      done(error);
    }
  })
);

passport.use(
  new JWTStrategy(
    {
      jwtFromRequest: req => req.headers.authorization.split(" ")[1],
      secretOrKey: process.env.APP_SECRET
    },
    (jwtPayload, done) => {
      if (Date.now() > jwtPayload.expires) {
        return done("jwt expired");
      }

      return done(null, jwtPayload);
    }
  )
);

module.exports = passport;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...