Skip to content

Commit

Permalink
Testing new Routes feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
igoramadas committed Oct 11, 2019
1 parent eb9b5e3 commit f074f52
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 81 deletions.
4 changes: 3 additions & 1 deletion lib/routes.d.ts
Expand Up @@ -2,6 +2,8 @@
interface LoadOptions {
/** The actual routes implementation. */
handlers: any;
/** The actual routes specs (for either plain routes or swagger). */
specs?: any;
/** The file containing routes to be loaded. */
filename?: string;
/** Optional version of the API / routes / swagger. */
Expand All @@ -16,7 +18,7 @@ declare class Routes {
newInstance(): Routes;
/**
* Load routes from the specified file.
* @param options Loading options with filename and handlers.
* @param options Loading options with filename or specs, and handlers.
*/
load: (options: LoadOptions) => void;
/**
Expand Down
90 changes: 52 additions & 38 deletions lib/routes.js
Expand Up @@ -13,35 +13,41 @@ class Routes {
// --------------------------------------------------------------------------
/**
* Load routes from the specified file.
* @param options Loading options with filename and handlers.
* @param options Loading options with filename or specs, and handlers.
*/
this.load = (options) => {
logger.debug("Routes.load", options.filename, Object.keys(options.handlers));
let specs;
// Check if the handlers were passed.
if (options.handlers == null) {
if (options == null || options.handlers == null) {
throw new Error(`Missing options.handlers with the routing functions`);
}
// Default filename is taken from settings.
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.filename;
}
const filename = jaul.io.getFilePath(options.filename);
let jsonRoutes;
// Check if file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`);
// Specs passed directly?
if (options.specs) {
specs = options.specs;
}
// Try loading the routes file.
try {
jsonRoutes = fs.readFileSync(filename, { encoding: settings.general.encoding }).toString();
jsonRoutes = JSON.parse(jsonRoutes);
}
catch (ex) {
logger.error("Routes.load", filename, ex);
throw ex;
// Otherwise load from filename.
else {
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.filename;
}
const filename = jaul.io.getFilePath(options.filename);
// Check if file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`);
}
// Try loading the routes file.
try {
specs = fs.readFileSync(filename, { encoding: settings.general.encoding }).toString();
specs = JSON.parse(specs);
}
catch (ex) {
logger.error("Routes.load", filename, ex);
throw ex;
}
}
// Iterate routes and handlers.
for (let [route, spec] of Object.entries(jsonRoutes)) {
for (let [route, spec] of Object.entries(specs)) {
if (_.isString(spec)) {
spec = { get: spec };
}
Expand All @@ -50,9 +56,11 @@ class Routes {
// Make sure method and handler are valid.
if (app[method] == null) {
logger.error("Routes.load", options.filename, route, `Invalid method: ${method}`);
throw new Error(`Invalid method: ${method}`);
}
else if (handler == null) {
logger.error("Routes.load", options.filename, route, `Invalid handler: ${handlerKey}`);
throw new Error(`Invalid handler: ${handlerKey}`);
}
else {
app[method](route, handler);
Expand All @@ -69,28 +77,34 @@ class Routes {
*/
this.loadSwagger = (options) => {
logger.debug("Routes.loadSwagger", options.filename, Object.keys(options.handlers));
let specs;
// Check if the handlers were passed.
if (options.handlers == null) {
if (options == null || options.handlers == null) {
throw new Error(`Missing options.handlers with the routing functions`);
}
// Default swagger filename is taken from settings.
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.swagger.filename;
// Specs passed directly?
if (options.specs) {
specs = options.specs;
}
const filename = jaul.io.getFilePath(options.filename);
// Check if swagger file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`);
}
let specs;
// Try loading the swagger file.
try {
specs = fs.readFileSync(filename, { encoding: settings.general.encoding }).toString();
specs = JSON.parse(specs);
}
catch (ex) {
logger.error("Routes.loadSwagger", filename, ex);
throw ex;
// Otherwise load from filename.
else {
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.swagger.filename;
}
const filename = jaul.io.getFilePath(options.filename);
// Check if swagger file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`);
}
// Try loading the swagger file.
try {
specs = fs.readFileSync(filename, { encoding: settings.general.encoding }).toString();
specs = JSON.parse(specs);
}
catch (ex) {
logger.error("Routes.loadSwagger", filename, ex);
throw ex;
}
}
// Version was passed as option?
if (options.version != null) {
Expand Down
89 changes: 52 additions & 37 deletions src/routes.ts
Expand Up @@ -11,6 +11,8 @@ const settings = require("setmeup").settings
interface LoadOptions {
/** The actual routes implementation. */
handlers: any
/** The actual routes specs (for either plain routes or swagger). */
specs?: any
/** The file containing routes to be loaded. */
filename?: string
/** Optional version of the API / routes / swagger. */
Expand All @@ -35,40 +37,46 @@ class Routes {

/**
* Load routes from the specified file.
* @param options Loading options with filename and handlers.
* @param options Loading options with filename or specs, and handlers.
*/
load = (options: LoadOptions) => {
logger.debug("Routes.load", options.filename, Object.keys(options.handlers))
let specs: any

// Check if the handlers were passed.
if (options.handlers == null) {
if (options == null || options.handlers == null) {
throw new Error(`Missing options.handlers with the routing functions`)
}

// Default filename is taken from settings.
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.filename
// Specs passed directly?
if (options.specs) {
specs = options.specs
}
// Otherwise load from filename.
else {
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.filename
}

const filename: string = jaul.io.getFilePath(options.filename)
let jsonRoutes
const filename: string = jaul.io.getFilePath(options.filename)

// Check if file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`)
}
// Check if file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`)
}

// Try loading the routes file.
try {
jsonRoutes = fs.readFileSync(filename, {encoding: settings.general.encoding}).toString()
jsonRoutes = JSON.parse(jsonRoutes)
} catch (ex) {
logger.error("Routes.load", filename, ex)
throw ex
// Try loading the routes file.
try {
specs = fs.readFileSync(filename, {encoding: settings.general.encoding}).toString()
specs = JSON.parse(specs)
} catch (ex) {
logger.error("Routes.load", filename, ex)
throw ex
}
}

// Iterate routes and handlers.
for (let [route, spec] of Object.entries(jsonRoutes)) {
for (let [route, spec] of Object.entries(specs)) {
if (_.isString(spec)) {
spec = {get: spec}
}
Expand All @@ -79,8 +87,10 @@ class Routes {
// Make sure method and handler are valid.
if (app[method] == null) {
logger.error("Routes.load", options.filename, route, `Invalid method: ${method}`)
throw new Error(`Invalid method: ${method}`)
} else if (handler == null) {
logger.error("Routes.load", options.filename, route, `Invalid handler: ${handlerKey}`)
throw new Error(`Invalid handler: ${handlerKey}`)
} else {
app[method](route, handler)
logger.info("Routes.load", options.filename, route, method, handlerKey)
Expand All @@ -98,33 +108,38 @@ class Routes {
*/
loadSwagger = (options: LoadOptions) => {
logger.debug("Routes.loadSwagger", options.filename, Object.keys(options.handlers))
let specs: any

// Check if the handlers were passed.
if (options.handlers == null) {
if (options == null || options.handlers == null) {
throw new Error(`Missing options.handlers with the routing functions`)
}

// Default swagger filename is taken from settings.
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.swagger.filename
// Specs passed directly?
if (options.specs) {
specs = options.specs
}
// Otherwise load from filename.
else {
if (options.filename == null || options.filename == "") {
options.filename = settings.routes.swagger.filename
}

const filename: string = jaul.io.getFilePath(options.filename)

// Check if swagger file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`)
}
const filename: string = jaul.io.getFilePath(options.filename)

let specs: any
// Check if swagger file exists.
if (filename == null || !fs.existsSync(filename)) {
throw new Error(`File ${options.filename} not found.`)
}

// Try loading the swagger file.
try {
specs = fs.readFileSync(filename, {encoding: settings.general.encoding}).toString()
specs = JSON.parse(specs)
} catch (ex) {
logger.error("Routes.loadSwagger", filename, ex)
throw ex
// Try loading the swagger file.
try {
specs = fs.readFileSync(filename, {encoding: settings.general.encoding}).toString()
specs = JSON.parse(specs)
} catch (ex) {
logger.error("Routes.loadSwagger", filename, ex)
throw ex
}
}

// Version was passed as option?
Expand Down
2 changes: 1 addition & 1 deletion test/sampleroutes.json
@@ -1,5 +1,5 @@
{
"/": "getHome",
"/": "getDefault",

"/abc": {
"get": "getAbc",
Expand Down
56 changes: 52 additions & 4 deletions test/test-routes.js
Expand Up @@ -18,8 +18,8 @@ describe("App Routes Tests", function() {
let supertest = null

let handlers = {
getHome: (req, res) => {
res.send("home")
getDefault: (req, res) => {
res.send("default")
},
getAbc: (req, res) => {
res.send("abc")
Expand All @@ -35,6 +35,23 @@ describe("App Routes Tests", function() {
}
}

let sampleSpecs = {
"/from-specs": "getDefault"
}

let sampleSwaggerSpecs = {
info: {
title: "Sample Swagger"
},
paths: {
"/from-swagger-specs": {
get: {
operationId: "getDefault"
}
}
}
}

before(async function() {
let port = await getPort(8008)
let logger = require("anyhow")
Expand Down Expand Up @@ -75,6 +92,12 @@ describe("App Routes Tests", function() {
supertest.post("/abc").expect(200, done)
})

it("Pass routes directly via options.specs", function(done) {
routes.load({handlers: handlers, specs: sampleSpecs})

supertest.get("/from-specs").expect(200, done)
})

it("Fails to load routes from incorrect files", function(done) {
try {
routes.load({filename: "notexisting.json"})
Expand All @@ -93,6 +116,12 @@ describe("App Routes Tests", function() {
try {
routes.load()
done("Calling load without passing handles should have failed.")
} catch (ex) {}

try {
sampleSpecs["/from-specs-invalid"] = "lalala"
routes.load({handlers: handlers, specs: sampleSpecs})
done("Should have failed to load with invalid lalala handler")
} catch (ex) {
done()
}
Expand All @@ -104,7 +133,16 @@ describe("App Routes Tests", function() {
supertest.get("/swagger/abc").expect(200, done)
})

it("Fails to load swagger specs from incorrect files", function(done) {
it("Pass swagger directly via options.specs", function(done) {
routes.loadSwagger({
handlers: handlers,
specs: sampleSwaggerSpecs
})

supertest.get("/from-swagger-specs").expect(200, done)
})

it("Fails to load swagger from incorrect files", function(done) {
try {
routes.loadSwagger({filename: "notexisting.json"})
done("Calling loadSwagger with non existing file should have failed.")
Expand All @@ -118,10 +156,20 @@ describe("App Routes Tests", function() {
}
})

it("Fails to load swagger specs with missing handlers", function(done) {
it("Fails to load swagger with missing handlers", function(done) {
try {
routes.loadSwagger()
done("Calling loadSwagger without passing handles should have failed.")
} catch (ex) {}

try {
sampleSwaggerSpecs.paths["/from-specs-invalid"] = {
get: {
operationId: "lalala"
}
}
routes.loadSwagger({handlers: handlers, specs: sampleSwaggerSpecs})
done("Should have failed to load swagger with invalid lalala handler")
} catch (ex) {
done()
}
Expand Down

0 comments on commit f074f52

Please sign in to comment.