From 845ca9301817676eefb53a33e868172e7de8c667 Mon Sep 17 00:00:00 2001 From: Mateusz Haligowski Date: Mon, 9 Sep 2024 08:22:09 -0700 Subject: [PATCH] Add Fetch API types as accepted mock parameters (#291) * Add Fetch API types as accepted mock parameters * Ran the formatter --------- Co-authored-by: Eugene Fidelin --- README.md | 21 +++++++++++++++++++-- lib/http-mock.d.ts | 15 +++++++++------ test/lib/http-mock.test-d.ts | 2 ++ test/lib/mockRequest.spec.ts | 7 ++++++- test/lib/mockResponse.spec.js | 7 +++---- 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 7f44aae..2636b6d 100644 --- a/README.md +++ b/README.md @@ -105,8 +105,8 @@ it('should handle expressjs requests', () => { ``` The expected type parameter in the mock request and response expects any type that extends the NodeJS -`http.IncomingRequest` interface. This means you can also mock requests coming from other frameworks -too. An example for NextJS request will look like this: +`http.IncomingRequest` interface or Fetch API `Request` class. This means you can also mock requests +coming from other frameworks too. An example for NextJS request will look like this: ```ts it('should handle nextjs requests', () => { @@ -123,6 +123,23 @@ it('should handle nextjs requests', () => { }); ``` +It is also possible to mock requests from the NextJS new AppRouter: + +```ts +it('should handle nextjs app reouter requests', () => { + const mockExpressRequest = httpMocks.createRequest({ + method: 'GET', + url: '/user/42', + params: { + id: 42 + } + }); + const mockExpressResponse = httpMocks.createResponse(); + + // ... the rest of the test as above. +}); +``` + ## API ### .createRequest() diff --git a/lib/http-mock.d.ts b/lib/http-mock.d.ts index c0eb3f1..b644c88 100644 --- a/lib/http-mock.d.ts +++ b/lib/http-mock.d.ts @@ -1,6 +1,9 @@ import { Request, Response, CookieOptions } from 'express'; import { IncomingMessage, OutgoingMessage } from 'http'; +export type RequestType = IncomingMessage | globalThis.Request; +export type ResponseType = OutgoingMessage | globalThis.Response; + export type RequestMethod = 'CONNECT' | 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE'; export interface Params { @@ -105,7 +108,7 @@ export interface RequestOptions { [key: string]: any; } -export type MockRequest = T & { +export type MockRequest = T & { _setParameter: (key: string, value?: string) => void; _setSessionVariable: (variable: string, value?: string) => void; _setCookiesVariable: (variable: string, value?: string) => void; @@ -134,7 +137,7 @@ export type ResponseCookie = { options: CookieOptions; }; -export type MockResponse = T & { +export type MockResponse = T & { _isEndCalled: () => boolean; _getHeaders: () => Headers; _getData: () => any; @@ -153,16 +156,16 @@ export type MockResponse = T & { cookies: { [name: string]: ResponseCookie }; }; -export function createRequest(options?: RequestOptions): MockRequest; +export function createRequest(options?: RequestOptions): MockRequest; -export function createResponse(options?: ResponseOptions): MockResponse; +export function createResponse(options?: ResponseOptions): MockResponse; -export interface Mocks { +export interface Mocks { req: MockRequest; res: MockResponse; } -export function createMocks( +export function createMocks( reqOptions?: RequestOptions, resOptions?: ResponseOptions ): Mocks; diff --git a/test/lib/http-mock.test-d.ts b/test/lib/http-mock.test-d.ts index 2934c95..ef38293 100644 --- a/test/lib/http-mock.test-d.ts +++ b/test/lib/http-mock.test-d.ts @@ -27,3 +27,5 @@ expectAssignable(createResponse()); expectNotAssignable(createResponse()); expectType>(createMocks()); +// eslint-disable-next-line no-undef +expectType>(createMocks()); diff --git a/test/lib/mockRequest.spec.ts b/test/lib/mockRequest.spec.ts index 32b58b8..d51834a 100644 --- a/test/lib/mockRequest.spec.ts +++ b/test/lib/mockRequest.spec.ts @@ -3,8 +3,8 @@ import * as url from 'url'; import * as querystring from 'querystring'; import parseRange from 'range-parser'; import { EventEmitter } from 'events'; - import { IncomingMessage } from 'http'; + import * as mockRequest from '../../lib/http-mock'; describe('mockRequest', () => { @@ -281,6 +281,11 @@ describe('mockRequest', () => { expect(request.ips).to.deep.equal([options.ip]); }); }); + + it('should be able to create a Fetch API Request object', () => { + const request = mockRequest.createRequest(); + expect(request.bodyUsed).to.be.undefined; + }); }); describe('.get()/.header()', () => { diff --git a/test/lib/mockResponse.spec.js b/test/lib/mockResponse.spec.js index 96a29fd..0af6482 100644 --- a/test/lib/mockResponse.spec.js +++ b/test/lib/mockResponse.spec.js @@ -1,14 +1,13 @@ const chai = require('chai'); - -const { expect } = chai; const sinon = require('sinon'); const sinonChai = require('sinon-chai'); -chai.use(sinonChai); - const mockResponse = require('../../lib/mockResponse'); const mockRequest = require('../../lib/mockRequest'); +const { expect } = chai; +chai.use(sinonChai); + describe('mockResponse', () => { it('should expose .createResponse()', () => { expect(mockResponse.createResponse).to.be.a('function');