9e583fa562
The problem before was that the pop() caused the open in existing instance functionality to break because the arguments no longer contained the file. We could simply remove the pop() but since `workspace` and `folder` are not CLI arguments I think it makes sense to handle them in a separate function which can be called at the point where they are needed. This also lets us de-duplicate some logic since we create these arguments in two spots and lets us skip this logic when we do not need it. The pop() is still avoided because manipulating a passed-in object in-place seems like a risky move. If we really need to do this we should copy the positional argument array instead.
117 lines
3.3 KiB
TypeScript
117 lines
3.3 KiB
TypeScript
import { logger } from "@coder/logger"
|
|
import * as express from "express"
|
|
import * as fs from "fs"
|
|
import * as path from "path"
|
|
import { HttpCode } from "../../../src/common/http"
|
|
import { AuthType } from "../../../src/node/cli"
|
|
import { codeServer, PluginAPI } from "../../../src/node/plugin"
|
|
import * as apps from "../../../src/node/routes/apps"
|
|
import * as httpserver from "../../utils/httpserver"
|
|
const fsp = fs.promises
|
|
|
|
// Jest overrides `require` so our usual override doesn't work.
|
|
jest.mock("code-server", () => codeServer, { virtual: true })
|
|
|
|
/**
|
|
* Use $LOG_LEVEL=debug to see debug logs.
|
|
*/
|
|
describe("plugin", () => {
|
|
let papi: PluginAPI
|
|
let s: httpserver.HttpServer
|
|
|
|
beforeAll(async () => {
|
|
// Only include the test plugin to avoid contaminating results with other
|
|
// plugins that might be on the filesystem.
|
|
papi = new PluginAPI(logger, `${path.resolve(__dirname, "test-plugin")}:meow`, "")
|
|
await papi.loadPlugins(false)
|
|
|
|
const app = express.default()
|
|
const wsApp = express.default()
|
|
|
|
const common: express.RequestHandler = (req, _, next) => {
|
|
// Routes might use these arguments.
|
|
req.args = {
|
|
_: [],
|
|
auth: AuthType.None,
|
|
host: "localhost",
|
|
port: 8080,
|
|
"proxy-domain": [],
|
|
config: "~/.config/code-server/config.yaml",
|
|
verbose: false,
|
|
usingEnvPassword: false,
|
|
usingEnvHashedPassword: false,
|
|
"extensions-dir": "",
|
|
"user-data-dir": "",
|
|
}
|
|
next()
|
|
}
|
|
|
|
app.use(common)
|
|
wsApp.use(common)
|
|
|
|
papi.mount(app, wsApp)
|
|
app.use("/api/applications", apps.router(papi))
|
|
|
|
s = new httpserver.HttpServer()
|
|
await s.listen(app)
|
|
s.listenUpgrade(wsApp)
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await s.dispose()
|
|
})
|
|
|
|
it("/api/applications", async () => {
|
|
const resp = await s.fetch("/api/applications")
|
|
expect(resp.status).toBe(200)
|
|
const body = await resp.json()
|
|
logger.debug(`${JSON.stringify(body)}`)
|
|
expect(body).toStrictEqual([
|
|
{
|
|
name: "Test App",
|
|
version: "4.0.0",
|
|
|
|
description: "This app does XYZ.",
|
|
iconPath: "/test-plugin/test-app/icon.svg",
|
|
homepageURL: "https://example.com",
|
|
path: "/test-plugin/test-app",
|
|
|
|
plugin: {
|
|
name: "test-plugin",
|
|
version: "1.0.0",
|
|
modulePath: path.join(__dirname, "test-plugin"),
|
|
|
|
displayName: "Test Plugin",
|
|
description: "Plugin used in code-server tests.",
|
|
routerPath: "/test-plugin",
|
|
homepageURL: "https://example.com",
|
|
},
|
|
},
|
|
])
|
|
})
|
|
|
|
it("/test-plugin/test-app", async () => {
|
|
const indexHTML = await fsp.readFile(path.join(__dirname, "test-plugin/public/index.html"), {
|
|
encoding: "utf8",
|
|
})
|
|
const resp = await s.fetch("/test-plugin/test-app")
|
|
expect(resp.status).toBe(200)
|
|
const body = await resp.text()
|
|
expect(body).toBe(indexHTML)
|
|
})
|
|
|
|
it("/test-plugin/test-app (websocket)", async () => {
|
|
const ws = s.ws("/test-plugin/test-app")
|
|
const message = await new Promise((resolve) => {
|
|
ws.once("message", (message) => resolve(message))
|
|
})
|
|
ws.terminate()
|
|
expect(message).toBe("hello")
|
|
})
|
|
|
|
it("/test-plugin/error", async () => {
|
|
const resp = await s.fetch("/test-plugin/error")
|
|
expect(resp.status).toBe(HttpCode.LargePayload)
|
|
})
|
|
})
|