Skip to content

Commit

Permalink
MiddlewareManager and -repository: Add additional unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
RandomByte committed Jul 3, 2019
1 parent 89b7b91 commit 8859ab0
Show file tree
Hide file tree
Showing 4 changed files with 300 additions and 21 deletions.
13 changes: 4 additions & 9 deletions lib/middleware/MiddlewareManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,12 @@ class MiddlewareManager {
`defines neither a "beforeMiddleware" nor an "afterMiddleware" parameter. One must be defined.`);
}

let newMiddlewareName = middlewareDef.name;
if (this.middleware[newMiddlewareName]) {
if (this.middleware[middlewareDef.name]) {
// Middleware is already known
// => add a suffix to allow for multiple configurations of the same middleware
let suffixCounter = 0;
while (this.middleware[newMiddlewareName]) {
suffixCounter++; // Start at 1
newMiddlewareName = `${middlewareDef.name}--${suffixCounter}`;
}
throw new Error(`Failed to add custom middleware ${middlewareDef.name}. ` +
`A middleware with the same name is already known.`);
}
await this.addMiddleware(newMiddlewareName, {
await this.addMiddleware(middlewareDef.name, {
wrapperCallback: (middleware) => {
return ({resources}) => {
const options = {
Expand Down
13 changes: 1 addition & 12 deletions lib/middleware/middlewareRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,7 @@ function addMiddleware(name, middlewarePath) {
middlewares[name] = middlewarePath;
}

function getAllMiddleware() {
const modules = {};
for (const middlewareName in middlewares) {
if (middlewares.hasOwnProperty(middlewareName)) {
modules[middlewareName] = require(middlewares[middlewareName]);
}
}
return middlewares;
}

module.exports = {
getMiddleware: getMiddleware,
addMiddleware: addMiddleware,
getAllMiddleware: getAllMiddleware
addMiddleware: addMiddleware
};
263 changes: 263 additions & 0 deletions test/lib/server/middleware/MiddlewareManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,266 @@ test("addMiddleware: Add middleware with async wrapperCallback", async (t) => {
t.deepEqual(middlewareManager.middleware["serveIndex"].middleware, "🍅",
"Middleware module is given");
});

test("addStandardMiddleware: Adds standard middleware in correct order", async (t) => {
const middlewareManager = new MiddlewareManager({
tree: {},
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
const addMiddlewareStub = sinon.stub(middlewareManager, "addMiddleware").resolves();
await middlewareManager.addStandardMiddleware();

t.deepEqual(addMiddlewareStub.callCount, 10, "Expected count of middleware got added");
const addedMiddlewareNames = [];
for (let i = 0; i < addMiddlewareStub.callCount; i++) {
addedMiddlewareNames.push(addMiddlewareStub.getCall(i).args[0]);
}
t.deepEqual(addedMiddlewareNames, [
"csp",
"compression",
"cors",
"discovery",
"serveResources",
"serveThemes",
"versionInfo",
"connectUi5Proxy",
"nonReadRequests",
"serveIndex"
], "Correct order of standard middlewares");
});

test("addCustomMiddleware: No custom middleware defined", async (t) => {
const project = {
server: {
customMiddleware: []
}
};
const middlewareManager = new MiddlewareManager({
tree: project,
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
const addMiddlewareStub = sinon.stub(middlewareManager, "addMiddleware").resolves();
await middlewareManager.addCustomMiddleware();

t.deepEqual(addMiddlewareStub.callCount, 0, "addMiddleware was not called");
});

test("addCustomMiddleware: Custom middleware got added", async (t) => {
const project = {
metadata: {
name: "my project"
},
server: {
customMiddleware: [{
name: "my custom middleware A",
beforeMiddleware: "cors",
mountPath: "/pony"
}, {
name: "my custom middleware B",
afterMiddleware: "my custom middleware A"
}]
}
};
const middlewareManager = new MiddlewareManager({
tree: project,
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
const addMiddlewareStub = sinon.stub(middlewareManager, "addMiddleware").resolves();
await middlewareManager.addCustomMiddleware();

t.deepEqual(addMiddlewareStub.callCount, 2, "addMiddleware was called twice");
t.deepEqual(addMiddlewareStub.getCall(0).args[0], "my custom middleware A",
"addMiddleware was called with correct middleware name");
const middlewareOptionsA = addMiddlewareStub.getCall(0).args[1];
t.deepEqual(middlewareOptionsA.mountPath, "/pony",
"addMiddleware was called with correct mountPath option");
t.deepEqual(middlewareOptionsA.beforeMiddleware, "cors",
"addMiddleware was called with correct beforeMiddleware option");
t.deepEqual(middlewareOptionsA.afterMiddleware, undefined,
"addMiddleware was called with correct afterMiddleware option");

t.deepEqual(addMiddlewareStub.getCall(1).args[0], "my custom middleware B",
"addMiddleware was called with correct middleware name");
const middlewareOptionsB = addMiddlewareStub.getCall(1).args[1];
t.deepEqual(middlewareOptionsB.mountPath, undefined,
"addMiddleware was called with correct mountPath option");
t.deepEqual(middlewareOptionsB.beforeMiddleware, undefined,
"addMiddleware was called with correct beforeMiddleware option");
t.deepEqual(middlewareOptionsB.afterMiddleware, "my custom middleware A",
"addMiddleware was called with correct afterMiddleware option");
});

test("addCustomMiddleware: Custom middleware with duplicate name", async (t) => {
const project = {
metadata: {
name: "my project"
},
server: {
customMiddleware: [{
name: "my custom middleware A",
afterMiddleware: "my custom middleware A"
}]
}
};
const middlewareManager = new MiddlewareManager({
tree: project,
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
middlewareManager.middleware["my custom middleware A"] = true;
const addMiddlewareStub = sinon.stub(middlewareManager, "addMiddleware").resolves();
const err = await t.throwsAsync(() => {
return middlewareManager.addCustomMiddleware();
});

t.deepEqual(err.message, "Failed to add custom middleware my custom middleware A. " +
"A middleware with the same name is already known.",
"Rejected with correct error message");
t.deepEqual(addMiddlewareStub.callCount, 0, "Add middleware did not get called");
});

test("addCustomMiddleware: Missing name configuration", async (t) => {
const project = {
metadata: {
name: "my project"
},
server: {
customMiddleware: [{
afterMiddleware: "my custom middleware A"
}]
}
};
const middlewareManager = new MiddlewareManager({
tree: project,
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
const err = await t.throwsAsync(() => {
return middlewareManager.addCustomMiddleware();
});

t.deepEqual(err.message, "Missing name for custom middleware definition of project my project at index 0",
"Rejected with correct error message");
});

test("addCustomMiddleware: Both before- and afterMiddleware configuration", async (t) => {
const project = {
metadata: {
name: "🐧"
},
server: {
customMiddleware: [{
name: "🦆",
beforeMiddleware: "🐝",
afterMiddleware: "🐒"
}]
}
};
const middlewareManager = new MiddlewareManager({
tree: project,
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
const err = await t.throwsAsync(() => {
return middlewareManager.addCustomMiddleware();
});

t.deepEqual(err.message, `Custom middleware definition 🦆 of project 🐧 ` +
`defines both "beforeMiddleware" and "afterMiddleware" parameters. Only one must be defined.`,
"Rejected with correct error message");
});

test("addCustomMiddleware: Missing before- or afterMiddleware configuration", async (t) => {
const project = {
metadata: {
name: "🐧"
},
server: {
customMiddleware: [{
name: "🦆"
}]
}
};
const middlewareManager = new MiddlewareManager({
tree: project,
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
const err = await t.throwsAsync(() => {
return middlewareManager.addCustomMiddleware();
});

t.deepEqual(err.message, `Custom middleware definition 🦆 of project 🐧 ` +
`defines neither a "beforeMiddleware" nor an "afterMiddleware" parameter. One must be defined.`,
"Rejected with correct error message");
});

test("addCustomMiddleware: wrapperCallback", async (t) => {
const project = {
metadata: {
name: "my project"
},
server: {
customMiddleware: [{
name: "my custom middleware A",
beforeMiddleware: "cors",
configuration: {
"🦊": "🐰"
}
}]
}
};
const middlewareManager = new MiddlewareManager({
tree: project,
resources: {
all: "I",
rootProject: "like",
dependencies: "ponies"
}
});
const addMiddlewareStub = sinon.stub(middlewareManager, "addMiddleware").resolves();
await middlewareManager.addCustomMiddleware();

t.deepEqual(addMiddlewareStub.callCount, 1, "addMiddleware was called once");

const wrapperCallback = addMiddlewareStub.getCall(0).args[1].wrapperCallback;
const middlewareModuleStub = sinon.stub().returns("ok");
const middlewareWrapper = wrapperCallback(middlewareModuleStub);
const res = middlewareWrapper({
resources: "resources"
});
t.deepEqual(res, "ok", "Wrapper callback returned expected value");
t.deepEqual(middlewareModuleStub.callCount, 1, "Middleware module got called once");
t.deepEqual(middlewareModuleStub.getCall(0).args[0], {
resources: "resources",
options: {
configuration: {
"🦊": "🐰"
}
}
}, "Middleware module got called with correct arguments");
});
32 changes: 32 additions & 0 deletions test/lib/server/middleware/middlewareRepository.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const test = require("ava");
const middlewareRepository = require("../../../../lib/middleware/middlewareRepository");

test("getMiddleware", async (t) => {
const cspModule = require("../../../../lib/middleware/csp");
const res = middlewareRepository.getMiddleware("csp");
t.is(res, cspModule, "Returned correct middleware module");
});

test("getMiddleware: Unkown middleware", async (t) => {
const err = t.throws(() => {
middlewareRepository.getMiddleware("🐬");
});
t.deepEqual(err.message, "middlewareRepository: Unknown Middleware 🐬",
"Threw error with correct message");
});

test("addMiddleware", async (t) => {
const cspModule = require("../../../../lib/middleware/csp");
middlewareRepository.addMiddleware("🐠", "./csp");
const res = middlewareRepository.getMiddleware("🐠");

t.is(res, cspModule, "Returned added middleware module");
});

test("addMiddleware: Duplicate middleware", async (t) => {
const err = t.throws(() => {
middlewareRepository.addMiddleware("cors");
});
t.deepEqual(err.message, "middlewareRepository: Middleware cors already registered",
"Threw error with correct message");
});

0 comments on commit 8859ab0

Please sign in to comment.