kogosoftwarellc / open-api

A Monorepo of various packages to power OpenAPI in node
MIT License
895 stars 237 forks source link

Unable to test with jest/supertest #754

Closed pilotak closed 3 years ago

pilotak commented 3 years ago

When running the test with jest, routes from open-api are not available through exported app, I even tried to add a delay but that didn't help. If i add hard coded route it's there, so what is wrong?

When running the project via npm start everything is fine, it's only failing when testing.

app.ts

import express from 'express';
import { initialize } from 'express-openapi';
import { resolve } from 'path';
import { jwtAuth } from './functions/security';
import { docs } from './api-doc';
import cors from 'cors';

export const app = express();

app.use(cors());

initialize({
  apiDoc: docs,
  app: app,
  paths: resolve(__dirname, 'routes'),
  securityHandlers: {
    jwtAuth: jwtAuth,
  },
});

app.get('/v1/test', (_req, res, next) => {
  res.status(200).end();
});

app.use((req, res, next) => {
  console.warn('Invalid URL', req.originalUrl);
  res.status(404).json({ error: 'Not found' });
});

app.use(((err, _req, res, next) => {
  let message;

  if (typeof err.message === 'string') {
    message = { error: 'Server error' };
  } else if (err.status == 400) {
    const { errors } = err;
    message = { errors: errors };
  } else {
    message = err.message;
  }

  res.status(err.status).json(message);
}) as express.ErrorRequestHandler);

const port = parseInt(process.argv[2], 10);

if (port) {
  app.listen(port, () => {
    console.log('Server is running at http://localhost:%d', port);
  });
}

api.test.ts

import request from 'supertest';
import { app } from '../app';

describe('Misc', () => {
  test('Custom route', async () => {
    const res = await request(app).get('/v1/test');
    expect(res.status).toBe(200);
  });

  test('DOCS', async () => {
    const res = await request(app).get('/v1/docs');
    expect(res.status).toBe(200);
    expect(res.body).toHaveProperty('openapi');
  });
});
  Misc
    √ Custom route (29 ms)
    × DOCS (31 ms)

  ● Misc › DOCS

    expect(received).toBe(expected) // Object.is equality

    Expected: 200
    Received: 404

      10 |   test('DOCS', async () => {
      11 |     const res = await request(app).get('/v1/docs');
    > 12 |     expect(res.status).toBe(200);
         |                        ^
      13 |     expect(res.body).toHaveProperty('openapi');
      14 |   });
      15 | });

      at Object.<anonymous> (src/__tests__/misc.test.ts:12:24)

  console.warn
    Invalid URL /v1/docs

      24 |
      25 | app.use((req, res, next) => {
    > 26 |   console.warn('Invalid URL', req.originalUrl);
         |           ^
      27 |   res.status(404).json({ error: 'Not found' });
      28 | });
      29 |

full code https://github.com/pilotak/openapi-typescript-jwt/

pilotak commented 3 years ago

when running the test visitApi is called but visitOperation is not. When running normally - visitOperation is called

https://github.com/kogosoftwarellc/open-api/blob/bb744c6f6e2dce57bba2dc361604147882a108dc/packages/express-openapi/index.ts#L86

https://github.com/kogosoftwarellc/open-api/blob/bb744c6f6e2dce57bba2dc361604147882a108dc/packages/express-openapi/index.ts#L118

pilotak commented 3 years ago

Solve by adding allowing ts extension in initialize.

  routesGlob: '**/*.{ts,js}',
  routesIndexFileRegExp: /(?:index)?\.[tj]s$/,