#!/usr/bin/env node "use strict"; const assert = require("assert"); const http = require("http"); const path = require("path"); const { createV2xPreviewServer, isProxyPath, upstreamPath } = require("./v2x-preview-server"); async function listen(server) { await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); return server.address().port; } async function request(port, pathName, options = {}) { return new Promise((resolve, reject) => { const request = http.request({ hostname: "127.0.0.1", port, path: pathName, method: options.method || "GET", headers: options.headers }, (response) => { let body = ""; response.setEncoding("utf8"); response.on("data", (chunk) => { body += chunk; }); response.on("end", () => resolve({ status: response.statusCode, body, headers: response.headers })); }); request.on("error", reject); request.end(options.body); }); } (async () => { assert.equal(isProxyPath("/api/facilities/api/sys/login"), true); assert.equal(isProxyPath("/websocket/network/ws/network/obuPosition"), true); assert.equal(isProxyPath("/package/manifest.json"), false); assert.equal(upstreamPath("/api/facilities/api/sys/login?x=1"), "/facilities/api/sys/login?x=1"); assert.equal(upstreamPath("/websocket/network/ws/network/signal"), "/network/ws/network/signal"); // An upstream base path (deployments front the API as /dashboardApi) is kept. assert.equal(upstreamPath("/api/facilities/api/sys/login", "/dashboardApi"), "/dashboardApi/facilities/api/sys/login"); assert.equal(upstreamPath("/websocket/network/ws/x", "/dashboardWebsocket/"), "/dashboardWebsocket/network/ws/x"); assert.equal(upstreamPath("/api/x", "/"), "/x"); const upstream = http.createServer((req, res) => { let body = ""; req.on("data", (chunk) => { body += chunk; }); req.on("end", () => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({ method: req.method, path: req.url, body })); }); }); const upstreamPort = await listen(upstream); const preview = createV2xPreviewServer({ root: path.join(__dirname, "..", "outputs", "fengshu-er-road"), upstream: `http://127.0.0.1:${upstreamPort}`, }); const previewPort = await listen(preview); try { const proxied = await request(previewPort, "/api/facilities/api/sys/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: '{"userName":"test"}', }); assert.equal(proxied.status, 200); assert.deepEqual(JSON.parse(proxied.body), { method: "POST", path: "/facilities/api/sys/login", body: '{"userName":"test"}' }); const staticPage = await request(previewPort, "/fengshu-er-road-cesium-preview.html"); assert.equal(staticPage.status, 200); assert.match(staticPage.body, /Cesium Preview/); } finally { await Promise.all([new Promise((resolve) => preview.close(resolve)), new Promise((resolve) => upstream.close(resolve))]); } // Same upstream, but reached through a prefixed base path. const prefixedUpstream = http.createServer((req, res) => { res.setHeader("Content-Type", "application/json"); res.end(JSON.stringify({ path: req.url })); }); const prefixedPort = await listen(prefixedUpstream); const prefixedPreview = createV2xPreviewServer({ root: path.join(__dirname, "..", "outputs", "fengshu-er-road"), upstream: `http://127.0.0.1:${prefixedPort}/dashboardApi`, wsUpstream: `http://127.0.0.1:${prefixedPort}/dashboardWebsocket`, }); const prefixedPreviewPort = await listen(prefixedPreview); try { const proxied = await request(prefixedPreviewPort, "/api/facilities/api/sys/login"); assert.deepEqual(JSON.parse(proxied.body), { path: "/dashboardApi/facilities/api/sys/login" }); } finally { await Promise.all([ new Promise((resolve) => prefixedPreview.close(resolve)), new Promise((resolve) => prefixedUpstream.close(resolve)), ]); } console.log("V2X preview server tests passed."); })().catch((error) => { console.error(error); process.exitCode = 1; });