|
1 | 1 | import bodyParser from "body-parser"
|
2 | 2 | import * as express from "express"
|
| 3 | +import * as nodeFetch from "node-fetch" |
| 4 | +import * as http from "http" |
| 5 | +import { HttpCode } from "../../../src/common/http" |
| 6 | +import { proxy } from "../../../src/node/proxy" |
3 | 7 | import * as httpserver from "../../utils/httpserver"
|
4 | 8 | import * as integration from "../../utils/integration"
|
| 9 | +import { getAvailablePort } from "../../utils/helpers" |
5 | 10 |
|
6 | 11 | describe("proxy", () => {
|
7 | 12 | const nhooyrDevServer = new httpserver.HttpServer()
|
@@ -102,4 +107,109 @@ describe("proxy", () => {
|
102 | 107 | expect(resp.status).toBe(200)
|
103 | 108 | expect(await resp.json()).toBe("coder is the best")
|
104 | 109 | })
|
| 110 | + |
| 111 | + it("should handle bad requests", async () => { |
| 112 | + e.use(bodyParser.json({ strict: false })) |
| 113 | + e.post("/wsup", (req, res) => { |
| 114 | + res.json(req.body) |
| 115 | + }) |
| 116 | + codeServer = await integration.setup(["--auth=none"], "") |
| 117 | + const resp = await codeServer.fetch(proxyPath, { |
| 118 | + method: "post", |
| 119 | + body: "coder is the best", |
| 120 | + headers: { |
| 121 | + "Content-Type": "application/json", |
| 122 | + }, |
| 123 | + }) |
| 124 | + expect(resp.status).toBe(400) |
| 125 | + expect(resp.statusText).toMatch("Bad Request") |
| 126 | + }) |
| 127 | + |
| 128 | + it("should handle invalid routes", async () => { |
| 129 | + e.post("/wsup", (req, res) => { |
| 130 | + res.json(req.body) |
| 131 | + }) |
| 132 | + codeServer = await integration.setup(["--auth=none"], "") |
| 133 | + const resp = await codeServer.fetch(`${proxyPath}/hello`) |
| 134 | + expect(resp.status).toBe(404) |
| 135 | + expect(resp.statusText).toMatch("Not Found") |
| 136 | + }) |
| 137 | + |
| 138 | + it("should handle errors", async () => { |
| 139 | + e.use(bodyParser.json({ strict: false })) |
| 140 | + e.post("/wsup", (req, res) => { |
| 141 | + throw new Error("BROKEN") |
| 142 | + }) |
| 143 | + codeServer = await integration.setup(["--auth=none"], "") |
| 144 | + const resp = await codeServer.fetch(proxyPath, { |
| 145 | + method: "post", |
| 146 | + body: JSON.stringify("coder is the best"), |
| 147 | + headers: { |
| 148 | + "Content-Type": "application/json", |
| 149 | + }, |
| 150 | + }) |
| 151 | + expect(resp.status).toBe(500) |
| 152 | + expect(resp.statusText).toMatch("Internal Server Error") |
| 153 | + }) |
| 154 | +}) |
| 155 | + |
| 156 | +// NOTE@jsjoeio |
| 157 | +// Both this test suite and the one above it are very similar |
| 158 | +// The main difference is this one uses http and node-fetch |
| 159 | +// and specifically tests the proxy in isolation vs. using |
| 160 | +// the httpserver abstraction we've built. |
| 161 | +// |
| 162 | +// Leaving this as a separate test suite for now because |
| 163 | +// we may consider refactoring the httpserver abstraction |
| 164 | +// in the future. |
| 165 | +// |
| 166 | +// If you're writing a test specifically for code in |
| 167 | +// src/node/proxy.ts, you should probably add it to |
| 168 | +// this test suite. |
| 169 | +describe("proxy (standalone)", () => { |
| 170 | + let URL = "" |
| 171 | + let PROXY_URL = "" |
| 172 | + let testServer: http.Server |
| 173 | + let proxyTarget: http.Server |
| 174 | + |
| 175 | + beforeEach(async () => { |
| 176 | + const PORT = await getAvailablePort() |
| 177 | + const PROXY_PORT = await getAvailablePort() |
| 178 | + URL = `http://localhost:${PORT}` |
| 179 | + PROXY_URL = `http://localhost:${PROXY_PORT}` |
| 180 | + // Define server and a proxy server |
| 181 | + testServer = http.createServer((req, res) => { |
| 182 | + proxy.web(req, res, { |
| 183 | + target: PROXY_URL, |
| 184 | + }) |
| 185 | + }) |
| 186 | + |
| 187 | + proxyTarget = http.createServer((req, res) => { |
| 188 | + res.writeHead(200, { "Content-Type": "text/plain" }) |
| 189 | + res.end() |
| 190 | + }) |
| 191 | + |
| 192 | + // Start both servers |
| 193 | + await proxyTarget.listen(PROXY_PORT) |
| 194 | + await testServer.listen(PORT) |
| 195 | + }) |
| 196 | + |
| 197 | + afterEach(async () => { |
| 198 | + await testServer.close() |
| 199 | + await proxyTarget.close() |
| 200 | + }) |
| 201 | + |
| 202 | + it("should return a 500 when proxy target errors ", async () => { |
| 203 | + // Close the proxy target so that proxy errors |
| 204 | + await proxyTarget.close() |
| 205 | + const errorResp = await nodeFetch.default(`${URL}/error`) |
| 206 | + expect(errorResp.status).toBe(HttpCode.ServerError) |
| 207 | + expect(errorResp.statusText).toBe("Internal Server Error") |
| 208 | + }) |
| 209 | + |
| 210 | + it("should proxy correctly", async () => { |
| 211 | + const resp = await nodeFetch.default(`${URL}/route`) |
| 212 | + expect(resp.status).toBe(200) |
| 213 | + expect(resp.statusText).toBe("OK") |
| 214 | + }) |
105 | 215 | })
|
0 commit comments