mock-xmlhttprequest
Version:
XMLHttpRequest mock for testing
303 lines (301 loc) • 10.7 kB
text/typescript
/**
* mock-xmlhttprequest v8.4.1
* (c) 2025 Bertrand Guay-Paquet
* @license MIT
*/
import MockXhrRequest from './MockXhrRequest.cts';
import RequestData from './RequestData.cts';
import XhrEventTarget from './XhrEventTarget.cts';
import type { MockXhrResponseReceiver } from './MockXhrResponseReceiver.cts';
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;
}