mockttp
Version:
Mock HTTP server for testing HTTP clients and stubbing webservices
257 lines (256 loc) • 10.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebSocketRuleBuilder = void 0;
const websocket_step_definitions_1 = require("./websocket-step-definitions");
const base_rule_builder_1 = require("../base-rule-builder");
const matchers_1 = require("../matchers");
/**
* @class WebSocketRuleBuilder
* A builder for defining websocket mock rules. Create one using
* `.forAnyWebSocket(path)` on a Mockttp instance, then call whatever
* methods you'd like here to define more precise matching behaviour,
* control how the connection is handled, and how many times this
* rule should be applied.
*
* When you're done, call a `.thenX()` method to register the configured rule
* with the server. These return a promise for a MockedEndpoint, which can be
* used to verify the details of the requests matched by the rule.
*
* This returns a promise because rule registration can be asynchronous,
* either when using a remote server or testing in the browser. Wait for the
* promise returned by `.thenX()` methods to guarantee that the rule has taken
* effect before sending requests to it.
*/
class WebSocketRuleBuilder extends base_rule_builder_1.BaseRuleBuilder {
/**
* Mock rule builders should be constructed through the Mockttp instance you're
* using, not directly. You shouldn't ever need to call this constructor.
*/
constructor(addRule) {
super();
this.addRule = addRule;
this.steps = [];
// By default, websockets just match everything:
this.matchers.push(new matchers_1.WildcardMatcher());
}
/**
* Add a delay (in milliseconds) before the next step in the rule
*/
delay(ms) {
this.steps.push(new websocket_step_definitions_1.DelayStep(ms));
return this;
}
/**
* Pass matched websockets through to their real destination. This works
* for proxied requests only, and direct requests will be rejected with
* an error.
*
* This method takes options to configure how the request is passed
* through. See {@link PassThroughWebSocketStepOptions} for the full
* details of the options available.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
thenPassThrough(options = {}) {
this.steps.push(new websocket_step_definitions_1.PassThroughWebSocketStep(options));
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
/**
* Forward matched websockets on to the specified forwardToUrl. The url
* specified must not include a path or an error will be thrown.
* The path portion of the original request url is used instead.
*
* The url may optionally contain a protocol. If it does, it will override
* the protocol (and potentially the port, if unspecified) of the request.
* If no protocol is specified, the protocol (and potentially the port)
* of the original request URL will be used instead.
*
* This method takes options to configure how the request is passed
* through. See {@link PassThroughWebSocketStepOptions} for the full
* details of the options available.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
async thenForwardTo(target, options = {}) {
const protocolIndex = target.indexOf('://');
let { protocol, host } = protocolIndex !== -1
? { protocol: target.slice(0, protocolIndex), host: target.slice(protocolIndex + 3) }
: { host: target, protocol: null };
if (protocol === 'http')
protocol = 'ws';
if (protocol === 'https')
protocol = 'wss';
this.steps.push(new websocket_step_definitions_1.PassThroughWebSocketStep({
...options,
transformRequest: {
...options.transformRequest,
setProtocol: protocol,
replaceHost: { targetHost: host }
}
}));
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
/**
* Accept incoming WebSocket connections, and echo every message
* received on the WebSocket back to the client.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
thenEcho() {
this.steps.push(new websocket_step_definitions_1.EchoWebSocketStep());
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
/**
* Accept incoming WebSocket connections, and simply listen to
* incoming messages without ever sending anything in return.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
thenPassivelyListen() {
this.steps.push(new websocket_step_definitions_1.ListenWebSocketStep());
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
/**
* Rejects connections, sending an HTTP response with the given
* status, message and body, to explicitly refuse the WebSocket
* handshake.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
thenRejectConnection(statusCode, statusMessage, headers, body) {
this.steps.push(new websocket_step_definitions_1.RejectWebSocketStep(statusCode, statusMessage, headers, body));
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
/**
* Close connections that match this rule immediately, without accepting
* the socket or sending any other response.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
thenCloseConnection() {
this.steps.push(new websocket_step_definitions_1.CloseConnectionStep());
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
/**
* Reset connections that match this rule immediately, sending a TCP
* RST packet directly, without accepting the socket or sending any
* other response, and without cleanly closing the TCP connection.
*
* This is only supported in Node.js versions (>=16.17, >=18.3.0, or
* later), where `net.Socket` includes the `resetAndDestroy` method.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
thenResetConnection() {
this.steps.push(new websocket_step_definitions_1.ResetConnectionStep());
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
/**
* Hold open connections that match this rule, but never respond
* with anything at all, typically causing a timeout on the client side.
*
* Calling this method registers the rule with the server, so it
* starts to handle requests.
*
* This method returns a promise that resolves with a mocked endpoint.
* Wait for the promise to confirm that the rule has taken effect
* before sending requests to be matched. The mocked endpoint
* can be used to assert on the requests matched by this rule.
*
* @category Responses
*/
thenTimeout() {
this.steps.push(new websocket_step_definitions_1.TimeoutStep());
const rule = {
...this.buildBaseRuleData(),
steps: this.steps
};
return this.addRule(rule);
}
}
exports.WebSocketRuleBuilder = WebSocketRuleBuilder;
//# sourceMappingURL=websocket-rule-builder.js.map