UNPKG

rerumaccusamus

Version:

The meta-framework suite designed from scratch for frontend-focused modern web development.

348 lines (299 loc) 9.02 kB
import path from 'path'; import express from 'express'; import request from 'supertest'; import { serverManager } from '@modern-js/server-core'; import { INTROSPECTION_ROUTE_PATH } from '@modern-js/bff-utils'; import plugin from '../src/plugin'; import { APIPlugin } from './helpers'; import './common'; const pwd = path.join(__dirname, './fixtures/lambda-mode'); const API_DIR = './api'; describe('lambda-mode', () => { const id = '666'; const name = 'modern'; const foo = { id, name }; let apiHandler: any; beforeAll(async () => { const runner = await serverManager .clone() .usePlugin(APIPlugin, plugin) .init(); apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', prefix: '/api', }); }); test('should works', async () => { const res = await request(apiHandler).get('/api/hello'); expect(res.status).toBe(200); expect(res.body).toEqual({ message: 'hello' }); }); test('should works with query', async () => { const res = await request(apiHandler).get(`/api/nest/user?id=${id}`); expect(res.status).toBe(200); expect(res.body.query.id).toBe(id); }); test('should works with body', async () => { const res = await request(apiHandler).post('/api/nest/user').send(foo); expect(res.status).toBe(200); expect(res.body.data).toEqual(foo); }); test('should works with dynamic route ', async () => { const res = await request(apiHandler).post(`/api/nest/${id}`); expect(res.status).toBe(200); expect(res.body).toEqual({ id }); }); test('should works with context', async () => { const res = await request(apiHandler) .post(`/api/nest/user?id=${id}`) .send(foo); expect(res.status).toBe(200); expect(res.body.data).toEqual(foo); expect(res.body.query.id).toBe(id); }); test('should support cookies', async () => { const res = await request(apiHandler) .post(`/api/nest/user?id=${id}`) .set('Cookie', [`id=${id};name=${name}`]); expect(res.status).toBe(200); expect(res.body.cookies.id).toBe(id); expect(res.body.cookies.name).toBe(name); }); test('should works with schema', async () => { const res = await request(apiHandler).patch('/api/nest/user').send({ id: 777, name: 'xxx', }); expect(res.status).toBe(200); const res2 = await request(apiHandler).patch('/api/nest/user').send({ id: 'aaa', name: 'xxx', }); expect(res2.status).toBe(400); const res3 = await request(apiHandler).patch('/api/nest/user').send({ id: '777', name: 'xxx', }); expect(res3.status).toBe(500); }); test('introspection', async () => { const res = await request(apiHandler).get( `/api${INTROSPECTION_ROUTE_PATH}`, ); expect(res.status).toBe(200); expect(res.body.protocol).toBe('Farrow-API'); }); }); describe('add middwares', () => { let runner: any; beforeAll(async () => { serverManager.usePlugin(plugin); runner = await serverManager.init({}); }); test('should support add by function', async () => { const foo = 'foo'; const fakeMiddleware = jest.fn((req, res, next) => { next(); }); const fakeMiddleware2 = jest.fn((req, res) => { res.send(foo); }); // eslint-disable-next-line @typescript-eslint/naming-convention const [mock_fakeMiddleware, mock_fakeMiddleware2] = [ fakeMiddleware, fakeMiddleware2, ]; const apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', config: { middleware: [ mock_fakeMiddleware, mock_fakeMiddleware, mock_fakeMiddleware2, ], }, }); const res = await request(apiHandler).get('/user'); expect(fakeMiddleware.mock.calls.length).toBe(2); expect(fakeMiddleware2.mock.calls.length).toBe(1); expect(res.status).toBe(200); expect(res.text).toEqual(foo); }); test('should support add by string', async () => { const foo = 'foo'; const middleware1 = jest.fn((req, res, next) => { next(); }); const middleware2 = jest.fn((req, res) => { res.send(foo); }); const [mock_middleware1, mock_middleware2] = [middleware1, middleware2]; jest.mock( path.resolve(__dirname, './fixtures/middlewares/middleware1'), () => ({ __esModule: true, default: mock_middleware1, }), ); jest.mock( path.resolve(__dirname, './fixtures/middlewares/middleware2'), () => ({ __esModule: true, default: mock_middleware2, }), ); const apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', config: { middleware: [ require.resolve('./fixtures/middlewares/middleware1'), require.resolve('./fixtures/middlewares/middleware1'), require.resolve('./fixtures/middlewares/middleware2'), ], }, }); const res = await request(apiHandler).get('/user'); expect(middleware1.mock.calls.length).toBe(2); expect(middleware2.mock.calls.length).toBe(1); expect(res.status).toBe(200); expect(res.text).toEqual(foo); }); }); describe('support app.ts in lambda mode', () => { serverManager.usePlugin(APIPlugin, plugin); let runner: any; beforeAll(async () => { runner = await serverManager.init({}); }); beforeEach(() => { jest.resetModules(); }); test('support es module', async () => { const name = `modernjs`; const mock_express = express; jest.mock( path.join(pwd, 'app.ts'), () => { const app = mock_express(); return { __esModule: true, default: app, }; }, { virtual: true }, ); const apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', }); const res = await request(apiHandler).get(`/nest/user?name=${name}`); expect(res.status).toBe(200); expect(res.body.query.name).toBe(name); }); test('support commonjs module', async () => { const name = `modernjs`; const mock_express = express; jest.mock( path.join(pwd, API_DIR, 'app.ts'), () => { const app = mock_express(); return app; }, { virtual: true }, ); const apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', }); const res = await request(apiHandler).get(`/nest/user?name=${name}`); expect(res.status).toBe(200); expect(res.body.query.name).toBe(name); }); test('support use middleware', async () => { const name = `modernjs`; const mock_express = express; jest.mock( path.join(pwd, API_DIR, 'app.ts'), () => { const app = mock_express(); app.use((req, res, next) => { req.query.name = name; next(); }); return app; }, { virtual: true }, ); const apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', }); const res = await request(apiHandler).get(`/nest/user`); expect(res.status).toBe(200); expect(res.body.query.name).toBe(name); }); test('support use router', async () => { const name = `modernjs`; const mock_express = express; jest.mock( path.join(pwd, API_DIR, 'app.ts'), () => { const app = mock_express(); app.get('/hello', (req, res) => { res.send(`foo`); res.end(); }); return app; }, { virtual: true }, ); const apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', }); const res1 = await request(apiHandler).get(`/hello`); expect(res1.status).toBe(200); expect(res1.text).toBe('foo'); const res2 = await request(apiHandler).get(`/nest/user?name=${name}`); expect(res2.status).toBe(200); expect(res2.body.query.name).toBe(name); }); }); describe('support as async handler', () => { let runner: any; beforeAll(async () => { serverManager.usePlugin(plugin); runner = await serverManager.init({}); }); test('API handler should works', async () => { const foo = 'foo'; const order: number[] = []; const wrapMiddleware = jest.fn(async (req, res) => { await new Promise(resolve => { setTimeout(() => { order.push(1); resolve(true); }, 50); }); order.push(2); res.send(foo); }); const apiHandler = await runner.prepareApiServer({ pwd, mode: 'framework', config: { middleware: [wrapMiddleware] }, }); const asyncHandler = async (req: any, res: any) => { await apiHandler(req, res); order.push(3); }; const res = await request(asyncHandler).get('/user'); expect(wrapMiddleware.mock.calls.length).toBe(1); expect(order).toEqual([1, 2, 3]); expect(res.status).toBe(200); expect(res.text).toEqual(foo); }); });