Skip to content

Commit 197a09f

Browse files
committedNov 6, 2020
plugin: Test endpoints via supertest
Unfortunately we can't use node-mocks-http to test a express.Router that has async routes. See eugef/node-mocks-http#225 router will just return undefined if the executing handler is async and so the test will have no way to wait for it to complete. Thus, we have to use supertest which starts an actual HTTP server in the background and uses a HTTP client to send requests.
1 parent 9453f89 commit 197a09f

File tree

4 files changed

+132
-32
lines changed

4 files changed

+132
-32
lines changed
 

‎package.json

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@types/safe-compare": "^1.1.0",
4444
"@types/semver": "^7.1.0",
4545
"@types/split2": "^2.1.6",
46+
"@types/supertest": "^2.0.10",
4647
"@types/tar-fs": "^2.0.0",
4748
"@types/tar-stream": "^2.1.0",
4849
"@types/ws": "^7.2.6",
@@ -59,6 +60,7 @@
5960
"prettier": "^2.0.5",
6061
"stylelint": "^13.0.0",
6162
"stylelint-config-recommended": "^3.0.0",
63+
"supertest": "^6.0.1",
6264
"ts-node": "^9.0.0",
6365
"typescript": "4.0.2"
6466
},

‎test/plugin.test.ts

+40-26
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,57 @@
11
import { logger } from "@coder/logger"
2-
import * as assert from "assert"
32
import { describe } from "mocha"
43
import * as path from "path"
54
import { PluginAPI } from "../src/node/plugin"
5+
import * as supertest from "supertest"
6+
import * as express from "express"
7+
import * as apps from "../src/node/routes/apps"
68

79
/**
810
* Use $LOG_LEVEL=debug to see debug logs.
911
*/
1012
describe("plugin", () => {
11-
it("loads", async () => {
12-
const papi = new PluginAPI(logger, path.resolve(__dirname, "test-plugin") + ":meow")
13+
let papi: PluginAPI
14+
let app: express.Application
15+
let agent: supertest.SuperAgentTest
16+
17+
before(async () => {
18+
papi = new PluginAPI(logger, path.resolve(__dirname, "test-plugin") + ":meow")
1319
await papi.loadPlugins()
1420

15-
const apps = await papi.applications()
21+
app = express.default()
22+
papi.mount(app)
23+
24+
app.use("/api/applications", apps.router(papi))
25+
26+
agent = supertest.agent(app)
27+
})
28+
29+
it("/api/applications", async () => {
30+
await agent.get("/api/applications").expect(200, [
31+
{
32+
name: "Test App",
33+
version: "4.0.0",
34+
35+
description: "This app does XYZ.",
36+
iconPath: "/test-plugin/test-app/icon.svg",
37+
homepageURL: "https://example.com",
38+
path: "/test-plugin/test-app",
1639

17-
assert.deepEqual(
18-
[
19-
{
20-
name: "Test App",
21-
version: "4.0.0",
40+
plugin: {
41+
name: "test-plugin",
42+
version: "1.0.0",
43+
modulePath: path.join(__dirname, "test-plugin"),
2244

23-
description: "This app does XYZ.",
24-
iconPath: "/test-plugin/test-app/icon.svg",
45+
displayName: "Test Plugin",
46+
description: "Plugin used in code-server tests.",
47+
routerPath: "/test-plugin",
2548
homepageURL: "https://example.com",
26-
path: "/test-plugin/test-app",
27-
28-
plugin: {
29-
name: "test-plugin",
30-
version: "1.0.0",
31-
modulePath: path.join(__dirname, "test-plugin"),
32-
33-
displayName: "Test Plugin",
34-
description: "Plugin used in code-server tests.",
35-
routerPath: "/test-plugin",
36-
homepageURL: "https://example.com",
37-
},
3849
},
39-
],
40-
apps,
41-
)
50+
},
51+
])
52+
})
53+
54+
it("/test-plugin/test-app", async () => {
55+
await agent.get("/test-plugin/test-app").expect(200, { date: "2000-02-05T05:00:00.000Z" })
4256
})
4357
})

‎test/test-plugin/src/index.ts

+8-3
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@ export const plugin: pluginapi.Plugin = {
88
homepageURL: "https://example.com",
99
description: "Plugin used in code-server tests.",
1010

11-
init: (config) => {
11+
init(config) {
1212
config.logger.debug("test-plugin loaded!")
1313
},
1414

15-
router: () => {
15+
router() {
1616
const r = express.Router()
17+
r.get("/test-app", (req, res) => {
18+
res.json({
19+
date: new Date("2000/02/05"),
20+
})
21+
})
1722
r.get("/goland/icon.svg", (req, res) => {
1823
res.sendFile(fspath.resolve(__dirname, "../public/icon.svg"))
1924
})
2025
return r
2126
},
2227

23-
applications: () => {
28+
applications() {
2429
return [
2530
{
2631
name: "Test App",

‎yarn.lock

+82-3
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,11 @@
10351035
dependencies:
10361036
"@types/express" "*"
10371037

1038+
"@types/cookiejar@*":
1039+
version "2.1.2"
1040+
resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8"
1041+
integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==
1042+
10381043
"@types/eslint-visitor-keys@^1.0.0":
10391044
version "1.0.0"
10401045
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
@@ -1172,6 +1177,21 @@
11721177
dependencies:
11731178
"@types/node" "*"
11741179

1180+
"@types/superagent@*":
1181+
version "4.1.10"
1182+
resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-4.1.10.tgz#5e2cc721edf58f64fe9b819f326ee74803adee86"
1183+
integrity sha512-xAgkb2CMWUMCyVc/3+7iQfOEBE75NvuZeezvmixbUw3nmENf2tCnQkW5yQLTYqvXUQ+R6EXxdqKKbal2zM5V/g==
1184+
dependencies:
1185+
"@types/cookiejar" "*"
1186+
"@types/node" "*"
1187+
1188+
"@types/supertest@^2.0.10":
1189+
version "2.0.10"
1190+
resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.10.tgz#630d79b4d82c73e043e43ff777a9ca98d457cab7"
1191+
integrity sha512-Xt8TbEyZTnD5Xulw95GLMOkmjGICrOQyJ2jqgkSjAUR3mm7pAIzSR0NFBaMcwlzVvlpCjNwbATcWWwjNiZiFrQ==
1192+
dependencies:
1193+
"@types/superagent" "*"
1194+
11751195
"@types/tar-fs@^2.0.0":
11761196
version "2.0.0"
11771197
resolved "https://registry.yarnpkg.com/@types/tar-fs/-/tar-fs-2.0.0.tgz#db94cb4ea1cccecafe3d1a53812807efb4bbdbc1"
@@ -2182,7 +2202,7 @@ colorette@^1.2.1:
21822202
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
21832203
integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
21842204

2185-
combined-stream@^1.0.6, combined-stream@~1.0.6:
2205+
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
21862206
version "1.0.8"
21872207
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
21882208
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
@@ -2204,7 +2224,7 @@ commander@^5.0.0:
22042224
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
22052225
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
22062226

2207-
component-emitter@^1.2.1:
2227+
component-emitter@^1.2.1, component-emitter@^1.3.0:
22082228
version "1.3.0"
22092229
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
22102230
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
@@ -2276,6 +2296,11 @@ cookie@0.4.0:
22762296
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
22772297
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
22782298

2299+
cookiejar@^2.1.2:
2300+
version "2.1.2"
2301+
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
2302+
integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
2303+
22792304
copy-descriptor@^0.1.0:
22802305
version "0.1.1"
22812306
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
@@ -3351,6 +3376,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
33513376
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
33523377
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
33533378

3379+
fast-safe-stringify@^2.0.7:
3380+
version "2.0.7"
3381+
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
3382+
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
3383+
33543384
fastest-levenshtein@^1.0.12:
33553385
version "1.0.12"
33563386
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
@@ -3493,6 +3523,15 @@ forever-agent@~0.6.1:
34933523
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
34943524
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
34953525

3526+
form-data@^3.0.0:
3527+
version "3.0.0"
3528+
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
3529+
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
3530+
dependencies:
3531+
asynckit "^0.4.0"
3532+
combined-stream "^1.0.8"
3533+
mime-types "^2.1.12"
3534+
34963535
form-data@~2.3.2:
34973536
version "2.3.3"
34983537
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
@@ -3507,6 +3546,11 @@ format@^0.2.0:
35073546
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
35083547
integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=
35093548

3549+
formidable@^1.2.2:
3550+
version "1.2.2"
3551+
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9"
3552+
integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==
3553+
35103554
forwarded@~0.1.2:
35113555
version "0.1.2"
35123556
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
@@ -4807,7 +4851,7 @@ merge2@^1.2.3, merge2@^1.3.0:
48074851
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
48084852
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
48094853

4810-
methods@~1.1.2:
4854+
methods@1.1.2, methods@^1.1.2, methods@~1.1.2:
48114855
version "1.1.2"
48124856
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
48134857
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
@@ -4864,6 +4908,11 @@ mime@1.6.0:
48644908
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
48654909
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
48664910

4911+
mime@^2.4.6:
4912+
version "2.4.6"
4913+
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1"
4914+
integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==
4915+
48674916
mimic-fn@^1.0.0:
48684917
version "1.2.0"
48694918
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
@@ -6181,6 +6230,11 @@ qs@6.7.0:
61816230
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
61826231
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
61836232

6233+
qs@^6.9.4:
6234+
version "6.9.4"
6235+
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
6236+
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
6237+
61846238
qs@~6.5.2:
61856239
version "6.5.2"
61866240
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
@@ -7246,6 +7300,31 @@ sugarss@^2.0.0:
72467300
dependencies:
72477301
postcss "^7.0.2"
72487302

7303+
superagent@6.1.0:
7304+
version "6.1.0"
7305+
resolved "https://registry.yarnpkg.com/superagent/-/superagent-6.1.0.tgz#09f08807bc41108ef164cfb4be293cebd480f4a6"
7306+
integrity sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==
7307+
dependencies:
7308+
component-emitter "^1.3.0"
7309+
cookiejar "^2.1.2"
7310+
debug "^4.1.1"
7311+
fast-safe-stringify "^2.0.7"
7312+
form-data "^3.0.0"
7313+
formidable "^1.2.2"
7314+
methods "^1.1.2"
7315+
mime "^2.4.6"
7316+
qs "^6.9.4"
7317+
readable-stream "^3.6.0"
7318+
semver "^7.3.2"
7319+
7320+
supertest@^6.0.1:
7321+
version "6.0.1"
7322+
resolved "https://registry.yarnpkg.com/supertest/-/supertest-6.0.1.tgz#f6b54370de85c45d6557192c8d7df604ca2c9e18"
7323+
integrity sha512-8yDNdm+bbAN/jeDdXsRipbq9qMpVF7wRsbwLgsANHqdjPsCoecmlTuqEcLQMGpmojFBhxayZ0ckXmLXYq7e+0g==
7324+
dependencies:
7325+
methods "1.1.2"
7326+
superagent "6.1.0"
7327+
72497328
supports-color@7.1.0:
72507329
version "7.1.0"
72517330
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"

0 commit comments

Comments
 (0)