Passed
Push — main ( d13a4d...a77d33 )
by Lorenzo
01:16 queued 14s
created

TestRouter2.test   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
1
import { flushPromises } from '@test/utils/testUtils';
2
import * as http from 'http';
3
import { NextFunction, Request, Response } from 'express';
4
import request from 'supertest';
5
import ExpressBeans from '@/core/ExpressBeans';
6
import { Logger, Route, RouterBean } from '@/main';
7
import { logger } from '@/core';
8
import { Executor } from '@/core/Executor';
9
10
jest.mock('pino-http', () => ({
11
  pinoHttp: ({
12
    logger: loggerInstance,
13
    customSuccessMessage,
14
    customErrorMessage,
15
  }: {
16
    logger: Logger,
17
    customSuccessMessage: (req: Request, res: Response) => string,
18
    customErrorMessage: (req: Request, res: Response) => string
19
  }) => (req: Request, res: Response, next: NextFunction) => {
20
    if (res.err) {
21
      loggerInstance.error(customErrorMessage(req, res));
22
    } else {
23
      loggerInstance.info(customSuccessMessage(req, res));
24
    }
25
    next();
26
  },
27
  startTime: jest.requireActual('pino-http').startTime,
28
}));
29
jest.mock('@/core', () => ({
30
  registeredBeans: new Map(),
31
  registeredMethods: new Map(),
32
  logger: {
33
    info: jest.fn(),
34
    debug: jest.fn(),
35
    error: jest.fn(),
36
  },
37
}));
38
39
describe('ExpressBeans integration tests', () => {
40
  let server: http.Server;
41
  let server2: http.Server;
42
  let application: ExpressBeans;
43
  let application2: ExpressBeans;
44
  beforeEach(() => {
45
    jest.resetModules();
46
    jest.clearAllMocks();
47
    Executor.stopLifecycle();
48
  });
49
50
  afterEach(() => {
51
    server.close();
52
    if (server2) {
53
      server2.close();
54
    }
55
  });
56
57
  test('start of application', async () => {
58
    // GIVEN
59
    @RouterBean('/test')
60
    class TestRouter {
61
      @Route('GET', '/42')
62
      test(_req: Request, res: Response) {
63
        res.send('42 is the answer');
64
      }
65
    }
66
    application = new ExpressBeans({ listen: false, routerBeans: [TestRouter] });
67
    await flushPromises();
68
    server = application.listen(3001);
69
    await flushPromises();
70
71
    // WHEN
72
    const { text } = await request(server).get('/test/42').expect(200);
73
74
    // THEN
75
    expect(text).toBe('42 is the answer');
76
  });
77
78
  test('creation of a new application', async () => {
79
    // WHEN
80
    application = new ExpressBeans({ listen: false });
81
    server = application.getApp().listen(3000);
82
    await flushPromises();
83
84
    // THEN
85
    expect(application instanceof ExpressBeans).toBe(true);
86
  });
87
88
  test('start multiple applications', async () => {
89
    // GIVEN
90
    @RouterBean('/test1')
91
    class TestRouter1 {
92
      @Route('GET', '/42')
93
      test(_req: Request, res: Response) {
94
        res.send('42 is the answer');
95
      }
96
    }
97
    @RouterBean('/test2')
98
    class TestRouter2 {
99
      @Route('GET', '/thanks')
100
      test(_req: Request, res: Response) {
101
        res.send('for all the fish');
102
      }
103
    }
104
    application = new ExpressBeans({ listen: false, routerBeans: [TestRouter1] });
105
    application2 = new ExpressBeans({ listen: false, routerBeans: [TestRouter2] });
106
    await flushPromises();
107
    server = application.listen(4001);
108
    server2 = application2.listen(4002);
109
    await flushPromises();
110
    await Executor.getExecutionPhase('init');
111
    await flushPromises();
112
113
    // WHEN
114
    const { text } = await request(server).get('/test1/42').expect(200);
115
    const { text: text2 } = await request(server2).get('/test2/thanks').expect(200);
116
    await request(server).get('/test2/thanks').expect(404);
117
    await request(server2).get('/test1/42').expect(404);
118
119
    // THEN
120
    expect(text).toBe('42 is the answer');
121
    expect(text2).toBe('for all the fish');
122
  });
123
124
  test('logs incoming requests', async () => {
125
    // GIVEN
126
    const loggerMock = jest.mocked(logger);
127
    @RouterBean('/test')
128
    class TestRouter {
129
      @Route('GET', '/42')
130
      test(_req: Request, res: Response) {
131
        res.send('42 is the answer');
132
      }
133
    }
134
    application = new ExpressBeans({ listen: false, routerBeans: [TestRouter] });
135
    await flushPromises();
136
    await Executor.getExecutionPhase('init');
137
    server = application.listen(3001);
138
    await flushPromises();
139
140
    // WHEN
141
    await (await request(server).get('/test/42').expect(200));
142
143
    // THEN
144
    expect(loggerMock.info).toHaveBeenCalledWith('::ffff:127.0.0.1 - "GET /test/42 HTTP/1.1" 200 - NaNms');
145
  });
146
147
  test('logs incoming requests using ip from header (proxy)', async () => {
148
    // GIVEN
149
    const loggerMock = jest.mocked(logger);
150
    @RouterBean('/test')
151
    class TestRouter {
152
      @Route('GET', '/42')
153
      test(_req: Request, res: Response) {
154
        res.send('42 is the answer');
155
      }
156
    }
157
    application = new ExpressBeans({ listen: false, routerBeans: [TestRouter] });
158
    await flushPromises();
159
    server = application.listen(3001);
160
    await Executor.getExecutionPhase('init');
161
    await flushPromises();
162
163
    // WHEN
164
    await (await request(server).get('/test/42').set({ 'x-forwarded-for': '193.234.61.32' }).expect(200));
165
166
    // THEN
167
    expect(loggerMock.info).toHaveBeenCalledWith('193.234.61.32 - "GET /test/42 HTTP/1.1" 200 - NaNms');
168
  });
169
});
170