UNPKG

@intuitionrobotics/testelot

Version:
181 lines 6.42 kB
/* * Testelot is a typescript scenario composing framework * * Copyright (C) 2020 Intuition Robotics * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Created by IR on 3/18/17. */ import { Exception, ImplementationMissingException, regexpCase, } from "@intuitionrobotics/ts-common"; import { Action } from "./Action.js"; import * as fetch from "node-fetch"; export var HttpMethod; (function (HttpMethod) { HttpMethod["ALL"] = "all"; HttpMethod["POST"] = "post"; HttpMethod["GET"] = "get"; HttpMethod["PATCH"] = "patch"; HttpMethod["DELETE"] = "delete"; HttpMethod["PUT"] = "put"; HttpMethod["OPTIONS"] = "options"; HttpMethod["HEAD"] = "head"; })(HttpMethod || (HttpMethod = {})); export class Action_Http extends Action { headers = {}; method; params = {}; url; body; responseStatus = 200; responseProcessor; static global_resolveResponseBody; constructor(method) { super(Action_Http); this.method = method; } setUrl(url) { this.url = url; return this; } ; setBody(body) { this.body = body; return this; } ; setParams(params) { this.params = params; return this; } ; addHeader(key, value) { this.headers[key] = value; return this; } ; setResponseStatus(status) { this.responseStatus = status; return this; } setResponseProcessor(validator) { this.responseProcessor = validator; return this; } resolveBody() { if (typeof this.body === "function") this.body = this.body(this); if (typeof this.body === "string") return this.body; this.addHeader("Accept", 'application/json'); this.addHeader("Content-Type", 'application/json'); return JSON.stringify(this.body, null, 2); } resolveUrl() { if (typeof this.url === "function") this.url = this.url(this); return this.url + `${this.toUrlParams()}`; } toUrlParams() { if (!this.params) return ""; if (typeof this.params === "function") this.params = this.params(); if (Object.keys(this.params).length === 0) return ""; return `?${Object.keys(this.params).map((key) => { return `${key}=${this.params[key]}`; }).join("&")}`; } async execute() { const url = this.resolveUrl(); const body = this.resolveBody(); const headers = {}; for (const key of Object.keys(this.headers)) { const value = this.headers[key]; if (typeof value !== "string") { headers[key] = value(this); } else headers[key] = value; } const requestBody = { headers: JSON.parse(JSON.stringify(headers)), body: body, method: this.method }; this.logInfo(`----- Method: ${requestBody.method}`); this.logInfo(`-------- Uri: ${url}`); if (Object.keys(headers).length > 0) { this.logVerbose("-------- Headers --------"); for (const key of Object.keys(headers)) { this.logVerbose(` ${key}: ${headers[key]}`); } this.logVerbose("-------------------------"); } if (requestBody.body) { this.logVerbose("--------- Request Body ----------"); this.logVerbose(body); this.logVerbose("-------------------------"); } return await this.executeHttpRequest(requestBody); } ; async resolveResponseBody(response) { const contentType = response.headers.get("Content-Type"); if (!contentType) return; switch (contentType) { case regexpCase(contentType, ".*application/json.*").input: return await response.json(); case regexpCase(contentType, ".*application/x-www-form-urlencoded.*").input: return decodeURI((await response.text())); case regexpCase(contentType, "^text\\/.*").input: return await response.text(); default: if (Action_Http.global_resolveResponseBody) return Action_Http.global_resolveResponseBody(this, response); } throw new ImplementationMissingException(`unhandled response with content-type: ${contentType}`); } async executeHttpRequest(requestBody) { const response = await fetch.default(this.resolveUrl(), requestBody); const status = response.status; let _responseBody = ""; const expectedStatus = this.responseStatus; if (status !== expectedStatus || status >= 500 && status < 600) { try { _responseBody = await response.text(); } catch (_ignore) { } this.logError(`Got Response code: ${status}`); this.logError(`Got Response body: ${_responseBody}`); throw new Exception(`wrong status code from server. Expected: ${expectedStatus} received: ${status}`); } // we don't want to undefine what was already defined just because we failed... if (status !== 200 && this.writeKey) this.get(this.writeKey); let responseBody = await this.resolveResponseBody(response); if (this.responseProcessor) responseBody = this.responseProcessor(responseBody); if (responseBody) { this.logVerbose("--------- Response ----------"); this.logVerbose(typeof responseBody === "object" ? JSON.stringify(responseBody, null, 2) : responseBody); this.logVerbose("-------------------------"); } return responseBody; } } //# sourceMappingURL=Action_Http.js.map