All files / src createGenericMockServer.ts

18.18% Statements 4/22
0% Branches 0/5
0% Functions 0/8
20% Lines 4/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 472x 2x                         2x 2x                                                              
import { IncomingMessage, RequestListener, createServer } from 'http';
import { getRandomPort } from 'get-port-please';
 
export type MockHandler = (req?: IncomingMessage) => Promise<{ body?: unknown; code?: number }>;
export type ListenerGenerator = (handler: MockHandler) => RequestListener;
 
/**
 * A factory to create a generic mocked HTTP server for testing purposes
 *
 * @param {ListenerGenerator} listenerGenerator Custom listener needed to instantiate the server
 * @param serverPort Optional server port
 * @returns {(handler: MockHandler) => { closeMock: () => Promise<void>; serverUrl: string }}
 * Object exposing close mock callback and server url
 */
export const createGenericMockServer =
  (listenerGenerator: ListenerGenerator, serverPort?: number) =>
  (handler: MockHandler = async () => ({})) =>
    // eslint-disable-next-line func-call-spacing
    new Promise<{ closeMock: () => Promise<void>; serverUrl: string }>(async (resolve, reject) => {
      try {
        const port = serverPort || (await getRandomPort());
        const server = createServer(listenerGenerator(handler));
 
        let resolver: () => void = jest.fn();
        let rejecter: (reason: unknown) => void = jest.fn();
 
        // eslint-disable-next-line @typescript-eslint/no-shadow
        const closePromise = new Promise<void>((resolve, reject) => {
          resolver = resolve;
          rejecter = reject;
        });
 
        server.on('error', rejecter);
        server.listen(port, 'localhost', () =>
          resolve({
            closeMock: () => {
              server.close((error) => (error ? rejecter(error) : resolver()));
              return closePromise;
            },
            serverUrl: `http://localhost:${port}`
          })
        );
      } catch (error) {
        reject(error);
      }
    });