From 05e49d9a96ef54f9e4bdb2cf7682098e2841712d Mon Sep 17 00:00:00 2001 From: Alex Kleissner Date: Wed, 10 Jun 2015 12:18:31 -0700 Subject: [PATCH] Move uncapitalize into its own file. refs #5286 - Moved the logic into its own file - Added unit tests --- core/server/middleware/index.js | 24 +---- core/server/middleware/uncapitalise.js | 35 ++++++ .../test/unit/middleware/uncapitalise_spec.js | 101 ++++++++++++++++++ 3 files changed, 137 insertions(+), 23 deletions(-) create mode 100644 core/server/middleware/uncapitalise.js create mode 100644 core/test/unit/middleware/uncapitalise_spec.js diff --git a/core/server/middleware/index.js b/core/server/middleware/index.js index 9b9aa5f587..f0247d3e0f 100644 --- a/core/server/middleware/index.js +++ b/core/server/middleware/index.js @@ -24,6 +24,7 @@ var api = require('../api'), utils = require('../utils'), sitemapHandler = require('../data/xml/sitemap/handler'), decideIsAdmin = require('./decide-is-admin'), + uncapitalise = require('./uncapitalise'), blogApp, setupMiddleware; @@ -152,29 +153,6 @@ function redirectToSetup(req, res, next) { }); } -// Detect uppercase in req.path -function uncapitalise(req, res, next) { - var pathToTest = req.path, - isSignupOrReset = req.path.match(/(\/ghost\/(signup|reset)\/)/i), - isAPI = req.path.match(/(\/ghost\/api\/v[\d\.]+\/.*?\/)/i); - - if (isSignupOrReset) { - pathToTest = isSignupOrReset[1]; - } - - // Do not lowercase anything after /api/v0.1/ to protect :key/:slug - if (isAPI) { - pathToTest = isAPI[1]; - } - - if (/[A-Z]/.test(pathToTest)) { - res.set('Cache-Control', 'public, max-age=' + utils.ONE_YEAR_S); - res.redirect(301, req.url.replace(pathToTest, pathToTest.toLowerCase())); - } else { - next(); - } -} - // ### ServeSharedFile Middleware // Handles requests to robots.txt and favicon.ico (and caches them) function serveSharedFile(file, type, maxAge) { diff --git a/core/server/middleware/uncapitalise.js b/core/server/middleware/uncapitalise.js new file mode 100644 index 0000000000..b2da052288 --- /dev/null +++ b/core/server/middleware/uncapitalise.js @@ -0,0 +1,35 @@ +// # uncapitalise Middleware +// Usage: uncapitalise(req, res, next) +// After: +// Before: +// App: Admin|Blog|API +// +// Detect upper case in req.path. + +var utils = require('../utils'), + uncapitalise; + +uncapitalise = function uncapitalise(req, res, next) { + /*jslint unparam:true*/ + var pathToTest = req.path, + isSignupOrReset = req.path.match(/(\/ghost\/(signup|reset)\/)/i), + isAPI = req.path.match(/(\/ghost\/api\/v[\d\.]+\/.*?\/)/i); + + if (isSignupOrReset) { + pathToTest = isSignupOrReset[1]; + } + + // Do not lowercase anything after /api/v0.1/ to protect :key/:slug + if (isAPI) { + pathToTest = isAPI[1]; + } + + if (/[A-Z]/.test(pathToTest)) { + res.set('Cache-Control', 'public, max-age=' + utils.ONE_YEAR_S); + res.redirect(301, req.url.replace(pathToTest, pathToTest.toLowerCase())); + } else { + next(); + } +}; + +module.exports = uncapitalise; diff --git a/core/test/unit/middleware/uncapitalise_spec.js b/core/test/unit/middleware/uncapitalise_spec.js new file mode 100644 index 0000000000..4a79fa3e17 --- /dev/null +++ b/core/test/unit/middleware/uncapitalise_spec.js @@ -0,0 +1,101 @@ +/*globals describe, beforeEach, afterEach, it*/ +/*jshint expr:true*/ +var sinon = require('sinon'), + uncapitalise = require('../../../server/middleware/uncapitalise'); + +describe('Middleware: uncapitalise', function () { + var sandbox, + res, + req, + next; + + beforeEach(function () { + sandbox = sinon.sandbox.create(); + + res = sinon.spy(); + req = sinon.spy(); + next = sinon.spy(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + describe('A signup or reset request', function () { + it('does nothing if there are no capital letters', function (done) { + req.path = '/ghost/signup'; + uncapitalise(req, res, next); + + next.should.be.calledOnce; + done(); + }); + + it('redirects to the lower case slug if there are capital letters', function (done) { + req.path = '/ghost/SignUP'; + req.url = 'http://localhost' + req.path; + res = { + redirect: sinon.spy(), + set: sinon.spy() + }; + + uncapitalise(req, res, next); + + next.should.not.be.called; + res.redirect.should.be.calledOnce; + res.redirect.calledWith(301, 'http://localhost/ghost/signup').should.be.true; + done(); + }); + }); + + describe('An API request', function () { + it('does nothing if there are no capital letters', function (done) { + req.path = '/ghost/api/v0.1'; + uncapitalise(req, res, next); + + next.should.be.calledOnce; + done(); + }); + + it('redirects to the lower case slug if there are capital letters', function (done) { + req.path = '/ghost/api/v0.1/ASDfJ'; + req.url = 'http://localhost' + req.path; + res = { + redirect: sinon.spy(), + set: sinon.spy() + }; + + uncapitalise(req, res, next); + + next.should.not.be.called; + res.redirect.should.be.calledOnce; + res.redirect.calledWith(301, 'http://localhost/ghost/api/v0.1/asdfj').should.be.true; + done(); + }); + }); + + describe('Any other request', function () { + it('does nothing if there are no capital letters', function (done) { + req.path = '/this-is-my-blog-post'; + uncapitalise(req, res, next); + + next.should.be.calledOnce; + done(); + }); + + it('redirects to the lower case slug if there are capital letters', function (done) { + req.path = '/THis-iS-my-BLOg-poSt'; + req.url = 'http://localhost' + req.path; + res = { + redirect: sinon.spy(), + set: sinon.spy() + }; + + uncapitalise(req, res, next); + + next.should.not.be.called; + res.redirect.should.be.calledOnce; + res.redirect.calledWith(301, 'http://localhost/this-is-my-blog-post').should.be.true; + done(); + }); + }); +});