diff --git a/samples/server/petstore/nodejs-express-server/.eslintrc b/samples/server/petstore/nodejs-express-server/.eslintrc new file mode 100644 index 000000000000..9e203a54733d --- /dev/null +++ b/samples/server/petstore/nodejs-express-server/.eslintrc @@ -0,0 +1,5 @@ +// Use this file as a starting point for your project's .eslintrc. +// Copy this file, and add rule overrides as needed. +{ + "extends": "airbnb" +} diff --git a/samples/server/petstore/nodejs-express-server/.openapi-generator/VERSION b/samples/server/petstore/nodejs-express-server/.openapi-generator/VERSION index afa636560641..717311e32e3c 100644 --- a/samples/server/petstore/nodejs-express-server/.openapi-generator/VERSION +++ b/samples/server/petstore/nodejs-express-server/.openapi-generator/VERSION @@ -1 +1 @@ -4.0.0-SNAPSHOT \ No newline at end of file +unset \ No newline at end of file diff --git a/samples/server/petstore/nodejs-express-server/config.js b/samples/server/petstore/nodejs-express-server/config.js new file mode 100644 index 000000000000..8eb547a8094a --- /dev/null +++ b/samples/server/petstore/nodejs-express-server/config.js @@ -0,0 +1,8 @@ +const path = require("path"); +const config = { + "ROOT_DIR": __dirname, + "URL_PORT": 3000 +}; +config.OPENAPI_YAML = path.join(config.ROOT_DIR, "api", "openapi.yaml"); + +module.exports = config; \ No newline at end of file diff --git a/samples/server/petstore/nodejs-express-server/config.json b/samples/server/petstore/nodejs-express-server/config.json new file mode 100644 index 000000000000..fcffb944b8f7 --- /dev/null +++ b/samples/server/petstore/nodejs-express-server/config.json @@ -0,0 +1,3 @@ +const { + "URL_PORT": 3000 +} \ No newline at end of file diff --git a/samples/server/petstore/nodejs-express-server/expressServer.js b/samples/server/petstore/nodejs-express-server/expressServer.js new file mode 100644 index 000000000000..0eccc19ad575 --- /dev/null +++ b/samples/server/petstore/nodejs-express-server/expressServer.js @@ -0,0 +1,65 @@ +'use strict'; +const Middleware= require("swagger-express-middleware").Middleware; +const swaggerUI = require("swagger-ui-express"); +const yamljs= require('yamljs'); +const express = require("express"); + +class ExpressServer{ + constructor(port, openApiYaml){ + this.port = port; + this.app = express(); + this.middleware = new Middleware(this.app); + this.swaggerJson = yamljs.load(openApiYaml); + this.setupMiddleware(); + } + setupMiddleware(){ + this.middleware.init(this.swaggerJson, (err) => { + this.app.use( + this.middleware.metadata(), + this.middleware.CORS(), + this.middleware.files( + { + apiPath: "api", + rawFilesPath: false + } + ), + this.middleware.parseRequest(), + this.middleware.validateRequest() + ); + }); + this.app.use("/api-docs", swaggerUI.serve, swaggerUI.setup(this.swaggerJson)); + this.app.get("/", (req, res, next) => { + res.status(200); + res.end("Hello World"); + }); + } + addErrorHandler(){ + this.app.use((error, req, res, next) => { + const status = error.status || 500; + res.status(status); + res.type("json"); + res.end({error}); + }); + } + async launch(){ + return new Promise( + async (resolve, reject) => { + try { + this.addErrorHandler(); + await this.app.listen(this.port, () => { + console.log(`server running on port ${this.port}`); + resolve(this.server); + }); + } catch (error) { + reject(error); + } + }); + } + async close(){ + if(this.server !== undefined){ + await this.server.close(); + console.log(`Server on port ${this.port} shut down`); + } + } +} + module.exports = ExpressServer; \ No newline at end of file diff --git a/samples/server/petstore/nodejs-express-server/index.js b/samples/server/petstore/nodejs-express-server/index.js index 58fcccb86263..72af4f380c35 100644 --- a/samples/server/petstore/nodejs-express-server/index.js +++ b/samples/server/petstore/nodejs-express-server/index.js @@ -1,44 +1,19 @@ -'use strict'; - -var fs = require('fs'), - path = require('path'), - http = require('http'); - -var app = require('connect')(); -var swaggerTools = require('swagger-tools'); -var jsyaml = require('js-yaml'); -var serverPort = 8080; - -// swaggerRouter configuration -var options = { - swaggerUi: path.join(__dirname, '/openapi.json'), - controllers: path.join(__dirname, './controllers'), - useStubs: process.env.NODE_ENV === 'development' // Conditionally turn on stubs (mock mode) +const ExpressServer = require("./expressServer"); +const config = require("./config"); +let expressServer; +launchServer = async() =>{ + try{ + expressServer = new ExpressServer(config.URL_PORT, config.OPENAPI_YAML); + await expressServer.launch(); + console.log("Express server running"); + + } + catch(error){ + if(expressServer !== undefined){ + expressServer.close(); + } + console.log("Error occured. Server closed", error); + } }; -// The Swagger document (require it, build it programmatically, fetch it from a URL, ...) -var spec = fs.readFileSync(path.join(__dirname,'api/openapi.yaml'), 'utf8'); -var swaggerDoc = jsyaml.safeLoad(spec); - -// Initialize the Swagger middleware -swaggerTools.initializeMiddleware(swaggerDoc, function (middleware) { - - // Interpret Swagger resources and attach metadata to request - must be first in swagger-tools middleware chain - app.use(middleware.swaggerMetadata()); - - // Validate Swagger requests - app.use(middleware.swaggerValidator()); - - // Route validated requests to appropriate controller - app.use(middleware.swaggerRouter(options)); - - // Serve the Swagger documents and Swagger UI - app.use(middleware.swaggerUi()); - - // Start the server - http.createServer(app).listen(serverPort, function () { - console.log('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort); - console.log('Swagger-ui is available on http://localhost:%d/docs', serverPort); - }); - -}); +launchServer(); \ No newline at end of file diff --git a/samples/server/petstore/nodejs-express-server/package.json b/samples/server/petstore/nodejs-express-server/package.json index 7b0f331cad58..2952d91d66f3 100644 --- a/samples/server/petstore/nodejs-express-server/package.json +++ b/samples/server/petstore/nodejs-express-server/package.json @@ -14,7 +14,20 @@ "private": true, "dependencies": { "connect": "^3.2.0", + "express": "^4.16.4", "js-yaml": "^3.3.0", - "swagger-tools": "0.10.1" + "swagger-express-middleware": "^2.0.2", + "swagger-tools": "0.10.1", + "swagger-ui-express": "^4.0.2", + "yamljs": "^0.3.0" + }, + "devDependencies": { + "axios": "^0.18.0", + "chai": "^4.2.0", + "chai-as-promised": "^7.1.1", + "eslint": "^5.16.0", + "eslint-config-airbnb-base": "^13.1.0", + "eslint-plugin-import": "^2.17.2", + "mocha": "^6.1.4" } } diff --git a/samples/server/petstore/nodejs-express-server/tests/serverTests.js b/samples/server/petstore/nodejs-express-server/tests/serverTests.js new file mode 100644 index 000000000000..ed28cdb70e29 --- /dev/null +++ b/samples/server/petstore/nodejs-express-server/tests/serverTests.js @@ -0,0 +1,56 @@ +const path = require("path"); +const describe = require("mocha").describe; +const chai = require("chai"); +const chaiAsPromised = require("chai-as-promised"); +const axios = require("axios"); +const ExpressServer = require("../expressServer"); + +chai.use(chaiAsPromised); +const should = chai.should(); + +const config = { + ROOT_DIR: path.join(__dirname, "../"), + URL_PORT: 3009 + }; +config.OPENAPI_YAML = path.join(config.ROOT_DIR, "api", "openapi.yaml"); + +describe("Server tests, checking launch, terminate, and various error messages", () =>{ + let expressServer; + before(async ()=>{ + try{ + expressServer = new ExpressServer(config.URL_PORT, config.OPENAPI_YAML); + await expressServer.launch(); + console.log("express server launched\n"); + } + catch(error){ + console.log(error); + throw(error); + } + }); + after(async() =>{ + if(expressServer !== undefined){ + await expressServer.close(); + console.log("express server closed"); + } + }); + it("should launch express server successfully", async() =>{ + const indexResponse = await axios.get(`http://localhost:${config.URL_PORT}/`); + indexResponse.status.should.equal(200, "Expecting a call to root directory of server to return 200 code"); + }); + it("should fail with a 404 on non-existing page", async() =>{ + try{ + const response = await axios.get(`http://localhost:${config.URL_PORT}/someRandomPage`); + response.status.should.not.equal(200, "Expecting a 404, got 200"); + } + catch(error){ + if(error.response !== undefined){ + error.response.status.should.equal(404, "expecting to receive a 404 on requesting a non-existing page"); + } + console.log(error); + } + }); + it("should load api-doc", async() =>{ + const response = await axios.get(`http://localhost:${config.URL_PORT}/api-docs`); + response.status.should.equal(200, "Expecting 200"); + }); +});