UNPKG

mock-xmlhttprequest

Version:
303 lines (301 loc) 10.7 kB
/** * mock-xmlhttprequest v8.4.1 * (c) 2025 Bertrand Guay-Paquet * @license MIT */ import MockXhrRequest from './MockXhrRequest.mts'; import RequestData from './RequestData.mts'; import XhrEventTarget from './XhrEventTarget.mts'; import type { MockXhrResponseReceiver } from './MockXhrResponseReceiver.mts'; export type OnCreateCallback = (xhr: MockXhr) => void; export type OnSendCallback = (this: MockXhrRequest, request: MockXhrRequest, xhr: MockXhr) => void; /** * XMLHttpRequest mock for testing. * Based on https://xhr.spec.whatwg.org version '15 August 2022'. * * Supports: * - Events and states * - open(), setRequestHeader(), send() and abort() * - Upload and download progress events * - Response status, statusText, headers and body * - The timeout attribute (can be disabled) * - Simulating a network error (see setNetworkError()) * - Simulating a request timeout (see setRequestTimeout()) * * Partial support: * - overrideMimeType(): throws when required, but has no other effect. * - responseType: '', 'text' and 'json' are fully supported. The responseType values have no * effect on the response body passed to setResponseBody(). * - responseXml: the response body is not converted to a document response. To get a document * response, pass it directly as the response body in setResponseBody(). * - responseUrl: the final request URL after redirects isn't automatically set. This can be * emulated in a request handler. * * Not supported: * - Synchronous requests (i.e. async set to false in open()) * - Parsing the request URL in open() and throwing SyntaxError on failure. */ export default class MockXhr extends XhrEventTarget implements XMLHttpRequest, MockXhrResponseReceiver { private _authorRequestHeaders; private _requestMethod?; private _requestUrl?; private _readyState; private _timeout; private _crossOriginCredentials; private _currentRequest?; private readonly _uploadObject; responseURL: string; private _responseType; private _response; private _sendFlag?; private _uploadListenerFlag?; private _uploadCompleteFlag?; private _timedOutFlag?; private _timeoutReference; private _timeoutTask?; constructor(); static readonly UNSENT = 0; static readonly OPENED = 1; static readonly HEADERS_RECEIVED = 2; static readonly LOADING = 3; static readonly DONE = 4; readonly UNSENT = 0; readonly OPENED = 1; readonly HEADERS_RECEIVED = 2; readonly LOADING = 3; readonly DONE = 4; get onreadystatechange(): ((this: XMLHttpRequest, ev: Event) => unknown) | null; set onreadystatechange(value: ((this: XMLHttpRequest, ev: Event) => unknown) | null); /** * Per-instance flag to enable the effects of the timeout attribute */ timeoutEnabled: boolean; /** * Global flag to enable the effects of the timeout attribute */ static timeoutEnabled: boolean; /** * Hook for creation of MockXhr instances */ static onCreate?: OnCreateCallback; /** * Per-instance hook for XMLHttpRequest.send(). Executes in an empty callstack. */ onSend?: OnSendCallback; /** * Global hook for XMLHttpRequest.send(). Executes in an empty callstack. */ static onSend?: OnSendCallback; /** * @returns The current active request, if any */ get currentRequest(): MockXhrRequest | undefined; /** * @returns All response headers as an object. The header names are in lower-case. */ getResponseHeadersHash(): Record<string, string>; /** * Fire a request upload progress event. * * @param request Originating request * @param requestBodyTransmitted Bytes transmitted * @see {@link https://xhr.spec.whatwg.org/#the-send()-method "processRequestBodyChunkLength" steps} */ uploadProgress(request: RequestData, requestBodyTransmitted: number): void; /** * Set the response headers. Changes the request's readyState to HEADERS_RECEIVED. * * @param request Originating request * @param status Response http status (default 200) * @param headers Name-value headers (optional) * @param statusText Response http status text (optional) */ setResponseHeaders(request: RequestData, status?: number, headers?: Record<string, string> | null, statusText?: string): void; /** * Fire a response progress event. Changes the request's readyState to LOADING. * * @param request Originating request * @param receivedBytesLength Received bytes' length * @param length Body length in bytes * @see {@link https://xhr.spec.whatwg.org/#the-send()-method "processBodyChunk" steps} */ downloadProgress(request: RequestData, receivedBytesLength: number, length: number): void; /** * Set the response body. Changes the request's readyState to DONE. * * @param request Originating request * @param body Response body */ setResponseBody(request: RequestData, body: unknown): void; /** * Simulate a network error. Changes the request's readyState to DONE. * * @param request Originating request */ setNetworkError(request: RequestData): void; /** * Simulate a request timeout. Changes the request's readyState to DONE. * * @param request Originating request */ setRequestTimeout(request: RequestData): void; /** * @returns Client's state * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate} */ get readyState(): number; /** * Set the request method and url. * * @param method Request HTTP method (GET, POST, etc.) * @param url Request url * @param async Async request flag (only true or omitted is supported) * @see {@link https://xhr.spec.whatwg.org/#the-open()-method} */ open(method: string, url: string | URL, async?: boolean): void; /** * Add a request header value. * * @param name Header name * @param value Header value * @see {@link https://xhr.spec.whatwg.org/#the-setrequestheader()-method} */ setRequestHeader(name: string, value: string): void; /** * @returns timeout attribute * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-timeout} */ get timeout(): number; /** * @param value timeout value * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-timeout} */ set timeout(value: number); /** * @returns withCredentials attribute * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-withcredentials} */ get withCredentials(): boolean; /** * @param value withCredentials value * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-withcredentials} */ set withCredentials(value: boolean); /** * @returns upload attribute * @see {@link https://xhr.spec.whatwg.org/#the-upload-attribute} */ get upload(): XhrEventTarget; /** * Initiate the request. * * @param body Request body * @see {@link https://xhr.spec.whatwg.org/#the-send()-method} */ send(body?: unknown): void; /** * Abort the request. * @see {@link https://xhr.spec.whatwg.org/#the-abort()-method} */ abort(): void; /** * @returns status attribute * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-status} */ get status(): number; /** * @returns statusText attribute * @see {@link https://xhr.spec.whatwg.org/#the-statustext-attribute} */ get statusText(): string; /** * Get a response header value. * * @param name Header name * @returns Header value * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getresponseheader} */ getResponseHeader(name: string): string | null; /** * Get all response headers as a string. * * @returns Concatenated headers * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-getallresponseheaders} */ getAllResponseHeaders(): string; /** * Throws when required, but has no other effect. * * @param mime MIME type * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-overridemimetype} */ overrideMimeType(mime: string): void; /** * @returns responseType attribute * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsetype} */ get responseType(): XMLHttpRequestResponseType; /** * @param value responseType value * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsetype} */ set responseType(value: XMLHttpRequestResponseType); /** * @returns response attribute * @see {@link https://xhr.spec.whatwg.org/#the-response-attribute} */ get response(): any; /** * @returns responseText attribute * @see {@link https://xhr.spec.whatwg.org/#the-responsetext-attribute} */ get responseText(): string; /** * @returns responseXML attribute * @see {@link https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsexml} */ get responseXML(): any; /** * Steps for when the request upload is complete. * * @param requestBodyTransmitted Bytes transmitted * @param requestBodyLength Request body's length * @see {@link https://xhr.spec.whatwg.org/#the-send()-method "processRequestEndOfBody" steps} */ private _processRequestEndOfBody; /** * Steps for when the response headers are received. * * @param response Response * @see {@link https://xhr.spec.whatwg.org/#the-send()-method "processResponse" steps} */ private _processResponse; /** * Handle response end-of-body for response. * * @see {@link https://xhr.spec.whatwg.org/#handle-response-end-of-body} */ private _handleResponseEndOfBody; /** * The "handle errors" steps. * * @see {@link https://xhr.spec.whatwg.org/#handle-errors} */ private _handleErrors; /** * The "request error steps" for event 'event'. * * @param event Event name * @see {@link https://xhr.spec.whatwg.org/#request-error-steps} */ private _requestErrorSteps; private _getTextResponse; protected _callOnSend(onSend?: OnSendCallback): void; private _terminateFetchController; private _fireProgressEvent; private _fireUploadProgressEvent; private _fireReadyStateChangeEvent; private _scheduleRequestTimeout; private _clearScheduleTimeout; private _getPrototype; }