i18next / i18next-express-middleware

[deprecated] can be replaced with i18next-http-middleware
https://github.com/i18next/i18next-http-middleware
MIT License
206 stars 52 forks source link

How to add it to jest test ? #208

Closed golubvladimir closed 4 years ago

golubvladimir commented 4 years ago

I have middleware for test:

module.exports = (req, res, next) =>  {
  const user = req.user;

  if (user.type !== 'admin') {
    return res.status(403).json({ error: req.t('errors.auth.access_error') });
  }

  next();
};

I have test file for it:

const express           = require('express');
const request           = require('supertest');

const i18next           = require('i18next');
const i18nextMiddleware = require('i18next-express-middleware');
const FilesystemBackend = require('i18next-node-fs-backend');
const path              = require('path');

const authenticateAdmin = require('../../../server/middleware/authenticateAdmin');

const app = express();

// Add i18n
i18next
  .use(i18nextMiddleware.LanguageDetector)
  .use(FilesystemBackend)
  .init({
    debug: false,
    fallbackLng: ['en'],
    preload: ['en', 'ru'],
    detection: {
      order: ['header', 'path'],
      lookupHeader: 'accept-language',
      lookupPath: 'lng',
      lookupFromPathIndex: 1,
      caches: false
    },
    backend: {
      loadPath: path.join(__dirname, '../../../lang/json/{{lng}}.json'),
      jsonIndent: 2,
    }
  });

app.use(
  // @see https://github.com/i18next/i18next-express-middleware/issues/201
  i18nextMiddleware.handle(i18next, {
    removeLngFromUrl: false
  })
);

describe('authenticate admin', () => {
  it('success', (done) => {
    const user = {
      name: 'Jack',
      type: 'admin'
    };

    app.post(
      '/',
      [
        (req, res, next) => {
          req.user = user;
          console.log(req.t('test'));
          next();
        },
        authenticateAdmin
      ],
      (req, res) => {
        res.status(200).json({ result: true });
      }
    );

    request(app)
      .post('/')
      .set('Accept-Language', 'en')
      .end((err, res) => {
        if (err) return done(err);

        expect(res.status).toEqual(200);
        expect(res.body.result).toBeTruthy();

        done();
      });
  });

  it('error', (done) => {
    const user = {
      name: 'Jack',
      type: 'manager'
    };

    app.post(
      '/',
      [
        (req, res, next) => {
          req.user = user;
          console.log(req.t('test'));
          next();
        },
        authenticateAdmin
      ],
      (req, res) => {
        res.status(200).json({ result: true });
      }
    );

    request(app)
      .post('/')
      .set('Accept-Language', 'en')
      .end((err, res) => {
        if (err) return done(err);

        expect(res.status).toEqual(403);
        expect(res.body.error).toEqual({ error: 'Access error' });

        done();
      });
  });
});

But instead of translations, I see it.

errors.auth.access_error
jamuhl commented 4 years ago

Test run before i18next finished initialization that's why you get the key as a fallback value...setting debug true you should see a warning about accessing t before it loaded the translations...

make sure in the test i18next is initialized eg. using the event: https://www.i18next.com/overview/api#oninitialized

golubvladimir commented 4 years ago

@jamuhl Thank you. It works.

const express           = require('express');
const request           = require('supertest');

const i18next           = require('i18next');
const i18nextMiddleware = require('i18next-express-middleware');
const FilesystemBackend = require('i18next-node-fs-backend');
const path              = require('path');

const app = express();

// Add i18n
i18next
  .use(i18nextMiddleware.LanguageDetector)
  .use(FilesystemBackend)
  .init({
    debug: false,
    fallbackLng: ['en'],
    preload: ['en', 'ru'],
    detection: {
      order: ['header', 'path'],
      lookupHeader: 'accept-language',
      lookupPath: 'lng',
      lookupFromPathIndex: 1,
      caches: false
    },
    backend: {
      loadPath: path.join(__dirname, '../../../lang/json/{{lng}}.json'),
      jsonIndent: 2,
    }
  });

// @see https://github.com/i18next/i18next-express-middleware/issues/201
app.use(
  i18nextMiddleware.handle(i18next, {
    removeLngFromUrl: false
  })
);

describe('test', () => {
  it('one', (done) => {
    app.post(
      '/',
      (req, res, next) => {
        console.log({ test: req.t('test') });

        next();
      },
      (req, res) => {
        return res.status(200).json({ result: true });
      }
    );

    i18next.on('initialized', () => {
      request(app)
        .post('/')
        .set('Accept-Language', 'en')
        .end((err, res) => {
          if (err) return done(err);

          expect({ a: 1 }).toEqual({ a: 1 });

          done();
        });
    });
  });
});