plugin: Test endpoints via supertest
Unfortunately we can't use node-mocks-http to test a express.Router that has async routes. See https://github.com/howardabrams/node-mocks-http/issues/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.
This commit is contained in:
parent
9453f891df
commit
197a09f0c1
@ -43,6 +43,7 @@
|
||||
"@types/safe-compare": "^1.1.0",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/split2": "^2.1.6",
|
||||
"@types/supertest": "^2.0.10",
|
||||
"@types/tar-fs": "^2.0.0",
|
||||
"@types/tar-stream": "^2.1.0",
|
||||
"@types/ws": "^7.2.6",
|
||||
@ -59,6 +60,7 @@
|
||||
"prettier": "^2.0.5",
|
||||
"stylelint": "^13.0.0",
|
||||
"stylelint-config-recommended": "^3.0.0",
|
||||
"supertest": "^6.0.1",
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "4.0.2"
|
||||
},
|
||||
|
@ -1,43 +1,57 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import * as assert from "assert"
|
||||
import { describe } from "mocha"
|
||||
import * as path from "path"
|
||||
import { PluginAPI } from "../src/node/plugin"
|
||||
import * as supertest from "supertest"
|
||||
import * as express from "express"
|
||||
import * as apps from "../src/node/routes/apps"
|
||||
|
||||
/**
|
||||
* Use $LOG_LEVEL=debug to see debug logs.
|
||||
*/
|
||||
describe("plugin", () => {
|
||||
it("loads", async () => {
|
||||
const papi = new PluginAPI(logger, path.resolve(__dirname, "test-plugin") + ":meow")
|
||||
let papi: PluginAPI
|
||||
let app: express.Application
|
||||
let agent: supertest.SuperAgentTest
|
||||
|
||||
before(async () => {
|
||||
papi = new PluginAPI(logger, path.resolve(__dirname, "test-plugin") + ":meow")
|
||||
await papi.loadPlugins()
|
||||
|
||||
const apps = await papi.applications()
|
||||
app = express.default()
|
||||
papi.mount(app)
|
||||
|
||||
assert.deepEqual(
|
||||
[
|
||||
{
|
||||
name: "Test App",
|
||||
version: "4.0.0",
|
||||
app.use("/api/applications", apps.router(papi))
|
||||
|
||||
description: "This app does XYZ.",
|
||||
iconPath: "/test-plugin/test-app/icon.svg",
|
||||
agent = supertest.agent(app)
|
||||
})
|
||||
|
||||
it("/api/applications", async () => {
|
||||
await agent.get("/api/applications").expect(200, [
|
||||
{
|
||||
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",
|
||||
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",
|
||||
},
|
||||
},
|
||||
],
|
||||
apps,
|
||||
)
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it("/test-plugin/test-app", async () => {
|
||||
await agent.get("/test-plugin/test-app").expect(200, { date: "2000-02-05T05:00:00.000Z" })
|
||||
})
|
||||
})
|
||||
|
@ -8,19 +8,24 @@ export const plugin: pluginapi.Plugin = {
|
||||
homepageURL: "https://example.com",
|
||||
description: "Plugin used in code-server tests.",
|
||||
|
||||
init: (config) => {
|
||||
init(config) {
|
||||
config.logger.debug("test-plugin loaded!")
|
||||
},
|
||||
|
||||
router: () => {
|
||||
router() {
|
||||
const r = express.Router()
|
||||
r.get("/test-app", (req, res) => {
|
||||
res.json({
|
||||
date: new Date("2000/02/05"),
|
||||
})
|
||||
})
|
||||
r.get("/goland/icon.svg", (req, res) => {
|
||||
res.sendFile(fspath.resolve(__dirname, "../public/icon.svg"))
|
||||
})
|
||||
return r
|
||||
},
|
||||
|
||||
applications: () => {
|
||||
applications() {
|
||||
return [
|
||||
{
|
||||
name: "Test App",
|
||||
|
85
yarn.lock
85
yarn.lock
@ -1035,6 +1035,11 @@
|
||||
dependencies:
|
||||
"@types/express" "*"
|
||||
|
||||
"@types/cookiejar@*":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8"
|
||||
integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==
|
||||
|
||||
"@types/eslint-visitor-keys@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||
@ -1172,6 +1177,21 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/superagent@*":
|
||||
version "4.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-4.1.10.tgz#5e2cc721edf58f64fe9b819f326ee74803adee86"
|
||||
integrity sha512-xAgkb2CMWUMCyVc/3+7iQfOEBE75NvuZeezvmixbUw3nmENf2tCnQkW5yQLTYqvXUQ+R6EXxdqKKbal2zM5V/g==
|
||||
dependencies:
|
||||
"@types/cookiejar" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/supertest@^2.0.10":
|
||||
version "2.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.10.tgz#630d79b4d82c73e043e43ff777a9ca98d457cab7"
|
||||
integrity sha512-Xt8TbEyZTnD5Xulw95GLMOkmjGICrOQyJ2jqgkSjAUR3mm7pAIzSR0NFBaMcwlzVvlpCjNwbATcWWwjNiZiFrQ==
|
||||
dependencies:
|
||||
"@types/superagent" "*"
|
||||
|
||||
"@types/tar-fs@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/tar-fs/-/tar-fs-2.0.0.tgz#db94cb4ea1cccecafe3d1a53812807efb4bbdbc1"
|
||||
@ -2182,7 +2202,7 @@ colorette@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b"
|
||||
integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==
|
||||
|
||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
||||
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
@ -2204,7 +2224,7 @@ commander@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
|
||||
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
|
||||
|
||||
component-emitter@^1.2.1:
|
||||
component-emitter@^1.2.1, component-emitter@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
|
||||
integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
|
||||
@ -2276,6 +2296,11 @@ cookie@0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
|
||||
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
|
||||
|
||||
cookiejar@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
|
||||
integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
|
||||
|
||||
copy-descriptor@^0.1.0:
|
||||
version "0.1.1"
|
||||
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:
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
fast-safe-stringify@^2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||
|
||||
fastest-levenshtein@^1.0.12:
|
||||
version "1.0.12"
|
||||
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2"
|
||||
@ -3493,6 +3523,15 @@ forever-agent@~0.6.1:
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
||||
|
||||
form-data@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
|
||||
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@~2.3.2:
|
||||
version "2.3.3"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
||||
@ -3507,6 +3546,11 @@ format@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
|
||||
integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=
|
||||
|
||||
formidable@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9"
|
||||
integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==
|
||||
|
||||
forwarded@~0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
|
||||
@ -4807,7 +4851,7 @@ merge2@^1.2.3, merge2@^1.3.0:
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
methods@~1.1.2:
|
||||
methods@1.1.2, methods@^1.1.2, methods@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
|
||||
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
|
||||
@ -4864,6 +4908,11 @@ mime@1.6.0:
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
|
||||
mime@^2.4.6:
|
||||
version "2.4.6"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1"
|
||||
integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==
|
||||
|
||||
mimic-fn@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||
@ -6181,6 +6230,11 @@ qs@6.7.0:
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
|
||||
|
||||
qs@^6.9.4:
|
||||
version "6.9.4"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
|
||||
integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
|
||||
|
||||
qs@~6.5.2:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
||||
@ -7246,6 +7300,31 @@ sugarss@^2.0.0:
|
||||
dependencies:
|
||||
postcss "^7.0.2"
|
||||
|
||||
superagent@6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/superagent/-/superagent-6.1.0.tgz#09f08807bc41108ef164cfb4be293cebd480f4a6"
|
||||
integrity sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==
|
||||
dependencies:
|
||||
component-emitter "^1.3.0"
|
||||
cookiejar "^2.1.2"
|
||||
debug "^4.1.1"
|
||||
fast-safe-stringify "^2.0.7"
|
||||
form-data "^3.0.0"
|
||||
formidable "^1.2.2"
|
||||
methods "^1.1.2"
|
||||
mime "^2.4.6"
|
||||
qs "^6.9.4"
|
||||
readable-stream "^3.6.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
supertest@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/supertest/-/supertest-6.0.1.tgz#f6b54370de85c45d6557192c8d7df604ca2c9e18"
|
||||
integrity sha512-8yDNdm+bbAN/jeDdXsRipbq9qMpVF7wRsbwLgsANHqdjPsCoecmlTuqEcLQMGpmojFBhxayZ0ckXmLXYq7e+0g==
|
||||
dependencies:
|
||||
methods "1.1.2"
|
||||
superagent "6.1.0"
|
||||
|
||||
supports-color@7.1.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1"
|
||||
|
Reference in New Issue
Block a user