diff --git a/mockServer.d.ts b/mockServer.d.ts index bcfa64a..bc4a677 100644 --- a/mockServer.d.ts +++ b/mockServer.d.ts @@ -309,8 +309,8 @@ export interface Ports { * verification sequence */ export type HttpRequestAndHttpResponse = { - httpRequest?: HttpRequest[]; - httpResponse?: HttpResponse[]; + httpRequest?: HttpRequest; + httpResponse?: HttpResponse; timestamp?: string; }; diff --git a/mockServerClient.d.ts b/mockServerClient.d.ts index 8ea1b45..8618aff 100644 --- a/mockServerClient.d.ts +++ b/mockServerClient.d.ts @@ -29,6 +29,27 @@ export type RequestResponse = SuccessFullRequest | string; export type PathOrRequestDefinition = string | Expectation | RequestDefinition | undefined | null; +export type ModifiableHttpRequest = Omit & { + headers: { [key: string]: string[] }; +}; + +export type ModifiableHttpResponse = Omit & { + headers: { [key: string]: string[] }; +}; + +export type HttpRequestCallbackHandler = ( + request: ModifiableHttpRequest +) => ModifiableHttpRequest; + +export type ModifiableHttpResponseAndRequest = { + httpRequest: ModifiableHttpRequest; + httpResponse: ModifiableHttpResponse; +}; + +export type HttpRequestResponseCallbackHandler = ( + requestAndResponse: ModifiableHttpResponseAndRequest +) => ModifiableHttpResponse; + export interface MockServerClient { openAPIExpectation(expectation: OpenAPIExpectation): Promise; @@ -52,7 +73,7 @@ export interface MockServerClient { clear(pathOrRequestDefinition: PathOrRequestDefinition, type: ClearType): Promise; - clearById(expectationId: ExpectationId, type: ClearType): Promise; + clearById(expectationId: string, type: ClearType): Promise; bind(ports: Port[]): Promise; @@ -65,6 +86,16 @@ export interface MockServerClient { retrieveRecordedExpectations(pathOrRequestDefinition: PathOrRequestDefinition): Promise; retrieveLogMessages(pathOrRequestDefinition: PathOrRequestDefinition): Promise; + + forwardWithCallback( + requestMatcher: RequestDefinition, + requestHandler: HttpRequestCallbackHandler, + requestAndResponseHandler: HttpRequestResponseCallbackHandler, + times?: Times | number, + priority?: number, + timeToLive?: TimeToLive, + id?: string + ): Promise; } /** diff --git a/mockServerClient.js b/mockServerClient.js index 28848a3..614312d 100644 --- a/mockServerClient.js +++ b/mockServerClient.js @@ -180,6 +180,35 @@ var mockServerClient; }; }; + var createForwardWithCallback = function (requestMatcher, clientId, times, priority, timeToLive, id, responseCallback) { + var timesObject; + if (typeof times === 'number') { + timesObject = { + remainingTimes: times, + unlimited: false + }; + } else if (typeof times === 'object') { + timesObject = times; + } + requestMatcher.headers = headersUniqueConcatenate(requestMatcher.headers, defaultRequestHeaders); + return { + id: typeof id === 'string' ? id : undefined, + priority: typeof priority === 'number' ? priority : undefined, + httpRequest: requestMatcher, + httpForwardObjectCallback: { + clientId: clientId, + responseCallback: responseCallback || false + }, + times: timesObject || { + remainingTimes: 1, + unlimited: false + }, + timeToLive: typeof timeToLive === 'object' ? timeToLive : { + unlimited: true + } + }; + }; + var WebSocketClient = (runningInNode() ? require('./webSocketClient').webSocketClient(tls, caCertPemFilePath) : function (host, port, contextPath) { var clientId; var clientIdHandler; @@ -384,6 +413,55 @@ var mockServerClient; var openAPIExpectation = function (expectation) { return makeRequest(host, port, "/mockserver/openapi", expectation); }; + + var forwardWithCallback = function (requestMatcher, requestHandler, requestAndResponseHandler, times, priority, timeToLive, id) { + return { + then: function (sucess, error) { + try { + var webSocketClientPromise = new WebSocketClient(host, port, cleanedContextPath); + webSocketClientPromise.then(function (webSocketClient) { + webSocketClient.requestCallback(function (request) { + var modifiedRequest = requestHandler(request); + modifiedRequest.headers = headersUniqueConcatenate(modifiedRequest.headers, [ + { + "name": "WebSocketCorrelationId", + "values": request.headers["WebSocketCorrelationId"] || request.headers["websocketcorrelationid"] + } + ]); + return { + type: "org.mockserver.model.HttpRequest", + value: JSON.stringify(modifiedRequest) + }; + }); + if (requestAndResponseHandler) { + webSocketClient.requestAndResponseCallback(function (requestAndResponse) { + var response = requestAndResponseHandler(requestAndResponse); + var headers = requestAndResponse.httpRequest.headers; + response.headers = headersUniqueConcatenate(response.headers, [ + { + "name": "WebSocketCorrelationId", + "values": headers["WebSocketCorrelationId"] || headers["websocketcorrelationid"] + } + ]); + return { + type: "org.mockserver.model.HttpResponse", + value: JSON.stringify(response) + }; + }); + } + webSocketClient.clientIdCallback(function (clientId) { + return makeRequest(host, port, "/mockserver/expectation", createForwardWithCallback(requestMatcher, clientId, times, priority, timeToLive, id, requestAndResponseHandler ? true : false)).then(sucess, error); + }); + }, error); + } catch (e) { + if (error) { + error(e); + } + } + } + }; + }; + /** * Setup an expectation by specifying a request matcher, and * a local request handler function. The request handler function receives each @@ -823,6 +901,7 @@ var mockServerClient; var _this = { openAPIExpectation: openAPIExpectation, mockAnyResponse: mockAnyResponse, + forwardWithCallback: forwardWithCallback, mockWithCallback: mockWithCallback, mockSimpleResponse: mockSimpleResponse, setDefaultHeaders: setDefaultHeaders, diff --git a/webSocketClient.js b/webSocketClient.js index 680ffd2..8b0b4db 100644 --- a/webSocketClient.js +++ b/webSocketClient.js @@ -74,6 +74,7 @@ var clientId; var clientIdHandler; var requestHandler; + var requestAndResponseHandler; var webSocketLocation = (tls ? "wss" : "ws") + "://" + host + ":" + port + contextPath + "/_mockserver_callback_websocket"; var client = new WebSocketClient({ @@ -105,14 +106,16 @@ connection.on('message', function (message) { if (message.type === 'utf8') { var payload = JSON.parse(message.utf8Data); + var value = JSON.parse(payload.value); if (payload.type === "org.mockserver.model.HttpRequest") { - var request = JSON.parse(payload.value); - var response = requestHandler(request); + var response = requestHandler(value); connection.sendUTF(JSON.stringify(response)); + } else if (payload.type === "org.mockserver.model.HttpRequestAndHttpResponse") { + var requestAndResponse = requestAndResponseHandler(value); + connection.sendUTF(JSON.stringify(requestAndResponse)); } else if (payload.type === "org.mockserver.serialization.model.WebSocketClientIdDTO") { - var registration = JSON.parse(payload.value); - if (registration.clientId) { - clientId = registration.clientId; + if (value.clientId) { + clientId = value.clientId; if (clientIdHandler) { clientIdHandler(clientId); } @@ -130,6 +133,9 @@ requestCallback: function requestCallback(callback) { requestHandler = callback; }, + requestAndResponseCallback: function requestAndResponseCallback(callback) { + requestAndResponseHandler = callback; + }, clientIdCallback: function clientIdCallback(callback) { clientIdHandler = callback; if (clientId) {