Skip to content

Commit 953f3a4

Browse files
committed
Add integration tests for vscode route
1 parent 08cc53f commit 953f3a4

File tree

2 files changed

+164
-2
lines changed

2 files changed

+164
-2
lines changed

test/unit/node/routes/vscode.test.ts

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import { promises as fs } from "fs"
2+
import { Response } from "node-fetch"
3+
import * as path from "path"
4+
import { clean, tmpdir } from "../../../utils/helpers"
5+
import * as httpserver from "../../../utils/httpserver"
6+
import * as integration from "../../../utils/integration"
7+
8+
interface WorkbenchConfig {
9+
folderUri?: {
10+
path: string
11+
}
12+
workspaceUri?: {
13+
path: string
14+
}
15+
}
16+
17+
describe("vscode", () => {
18+
let codeServer: httpserver.HttpServer | undefined
19+
20+
const testName = "vscode"
21+
beforeAll(async () => {
22+
await clean(testName)
23+
})
24+
25+
afterEach(async () => {
26+
if (codeServer) {
27+
await codeServer.dispose()
28+
codeServer = undefined
29+
}
30+
})
31+
32+
const routes = ["/", "/vscode", "/vscode/"]
33+
34+
it("should load all route variations", async () => {
35+
codeServer = await integration.setup(["--auth=none"], "")
36+
37+
for (const route of routes) {
38+
const resp = await codeServer.fetch(route)
39+
expect(resp.status).toBe(200)
40+
const html = await resp.text()
41+
const url = new URL(resp.url) // Check there were no redirections.
42+
expect(url.pathname + decodeURIComponent(url.search)).toBe(route)
43+
switch (route) {
44+
case "/":
45+
case "/vscode/":
46+
expect(html).toContain(`src="./static/`)
47+
break
48+
case "/vscode":
49+
expect(html).toContain(`src="./vscode/static/`)
50+
break
51+
}
52+
}
53+
})
54+
55+
/**
56+
* Get the workbench config from the provided response.
57+
*/
58+
const getConfig = async (resp: Response): Promise<WorkbenchConfig> => {
59+
expect(resp.status).toBe(200)
60+
const html = await resp.text()
61+
const match = html.match(/<meta id="vscode-workbench-web-configuration" data-settings="(.+)">/)
62+
if (!match || !match[1]) {
63+
throw new Error("Unable to find workbench configuration")
64+
}
65+
const config = match[1].replace(/&quot;/g, '"')
66+
try {
67+
return JSON.parse(config)
68+
} catch (error) {
69+
console.error("Failed to parse workbench configuration", config)
70+
throw error
71+
}
72+
}
73+
74+
it("should have no default folder or workspace", async () => {
75+
codeServer = await integration.setup(["--auth=none"], "")
76+
77+
const config = await getConfig(await codeServer.fetch("/"))
78+
expect(config.folderUri).toBeUndefined()
79+
expect(config.workspaceUri).toBeUndefined()
80+
})
81+
82+
it("should have a default folder", async () => {
83+
const defaultDir = await tmpdir(testName)
84+
codeServer = await integration.setup(["--auth=none", defaultDir], "")
85+
86+
// At first it will load the directory provided on the command line.
87+
const config = await getConfig(await codeServer.fetch("/"))
88+
expect(config.folderUri?.path).toBe(defaultDir)
89+
expect(config.workspaceUri).toBeUndefined()
90+
})
91+
92+
it("should have a default workspace", async () => {
93+
const defaultWorkspace = path.join(await tmpdir(testName), "test.code-workspace")
94+
await fs.writeFile(defaultWorkspace, "")
95+
codeServer = await integration.setup(["--auth=none", defaultWorkspace], "")
96+
97+
// At first it will load the workspace provided on the command line.
98+
const config = await getConfig(await codeServer.fetch("/"))
99+
expect(config.folderUri).toBeUndefined()
100+
expect(config.workspaceUri?.path).toBe(defaultWorkspace)
101+
})
102+
103+
it("should redirect to last query folder/workspace", async () => {
104+
codeServer = await integration.setup(["--auth=none"], "")
105+
106+
const folder = await tmpdir(testName)
107+
const workspace = path.join(await tmpdir(testName), "test.code-workspace")
108+
let resp = await codeServer.fetch("/", undefined, {
109+
folder,
110+
workspace,
111+
})
112+
expect(resp.status).toBe(200)
113+
await resp.text()
114+
115+
// If you visit again without query parameters it will re-attach them by
116+
// redirecting. It should always redirect to the same route.
117+
for (const route of routes) {
118+
resp = await codeServer.fetch(route)
119+
const url = new URL(resp.url)
120+
expect(url.pathname).toBe(route)
121+
expect(decodeURIComponent(url.search)).toBe(`?folder=${folder}&workspace=${workspace}`)
122+
await resp.text()
123+
}
124+
125+
// Closing the folder should stop the redirecting.
126+
resp = await codeServer.fetch("/", undefined, { ew: "true" })
127+
let url = new URL(resp.url)
128+
expect(url.pathname).toBe("/")
129+
expect(decodeURIComponent(url.search)).toBe("?ew=true")
130+
await resp.text()
131+
132+
resp = await codeServer.fetch("/")
133+
url = new URL(resp.url)
134+
expect(url.pathname).toBe("/")
135+
expect(decodeURIComponent(url.search)).toBe("")
136+
await resp.text()
137+
})
138+
139+
it("should not redirect when last opened is ignored", async () => {
140+
codeServer = await integration.setup(["--auth=none", "--ignore-last-opened"], "")
141+
142+
const folder = await tmpdir(testName)
143+
const workspace = path.join(await tmpdir(testName), "test.code-workspace")
144+
let resp = await codeServer.fetch("/", undefined, {
145+
folder,
146+
workspace,
147+
})
148+
expect(resp.status).toBe(200)
149+
await resp.text()
150+
151+
// No redirections.
152+
resp = await codeServer.fetch("/")
153+
const url = new URL(resp.url)
154+
expect(url.pathname).toBe("/")
155+
expect(decodeURIComponent(url.search)).toBe("")
156+
await resp.text()
157+
})
158+
})

test/utils/httpserver.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,17 @@ export class HttpServer {
5959
* fetch fetches the request path.
6060
* The request path must be rooted!
6161
*/
62-
public fetch(requestPath: string, opts?: RequestInit): Promise<Response> {
62+
public fetch(requestPath: string, opts?: RequestInit, query?: { [key: string]: string }): Promise<Response> {
6363
const address = ensureAddress(this.hs, "http")
6464
if (typeof address === "string") {
6565
throw new Error("Cannot fetch socket path")
6666
}
6767
address.pathname = requestPath
68-
68+
if (query) {
69+
Object.keys(query).forEach((key) => {
70+
address.searchParams.append(key, query[key])
71+
})
72+
}
6973
return nodeFetch(address.toString(), opts)
7074
}
7175

0 commit comments

Comments
 (0)