diff --git a/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js b/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js index 1d41fa7aeb..1f3aed6cb8 100644 --- a/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js +++ b/ghost/express-dynamic-redirects/test/DynamicRedirectManager.test.js @@ -13,11 +13,16 @@ const urlUtils = { describe('DynamicRedirectManager', function () { it('Prioritizes the query params of the redirect', function () { - const manager = new DynamicRedirectManager({permanentMaxAge: 100, getSubdirectoryURL: (pathname) => { - return urlUtils.urlJoin(urlUtils.getSubdir(), pathname); - }}); + const manager = new DynamicRedirectManager({ + permanentMaxAge: 100, + getSubdirectoryURL: (pathname) => { + return urlUtils.urlJoin(urlUtils.getSubdir(), pathname); + } + }); - manager.addRedirect('/test-params', '/result?q=abc', {permanent: true}); + manager.addRedirect('/test-params', '/result?q=abc', { + permanent: true + }); const req = { method: 'GET', @@ -38,7 +43,7 @@ describe('DynamicRedirectManager', function () { }; manager.handleRequest(req, res, function next() { - should.fail(true, false, 'next should not have been called'); + should.fail(true, false, 'next should NOT have been called'); }); should.equal(headers['Cache-Control'], 'public, max-age=100'); @@ -117,4 +122,168 @@ describe('DynamicRedirectManager', function () { should.equal(status, null); should.equal(location, null); }); + + describe('Substitution regex redirects', function () { + it('Works with substitution redirect case and no trailing slash', function (){ + const manager = new DynamicRedirectManager({ + permanentMaxAge: 100, + getSubdirectoryURL: (pathname) => { + return urlUtils.urlJoin(urlUtils.getSubdir(), pathname); + } + }); + const from = '^/post/[0-9]+/([a-z0-9\\-]+)'; + const to = '/$1'; + + manager.addRedirect(from , to); + + const req = { + method: 'GET', + url: '/post/10/a-nice-blog-post' + }; + + let headers = null; + let status = null; + let location = null; + const res = { + set(_headers) { + headers = _headers; + }, + redirect(_status, _location) { + status = _status; + location = _location; + } + }; + + manager.handleRequest(req, res, function next() { + should.fail(true, 'next should NOT have been called'); + }); + + // NOTE: max-age is "0" because it's not a permanent redirect + should.equal(headers['Cache-Control'], 'public, max-age=0'); + should.equal(status, 302); + should.equal(location, '/a-nice-blog-post'); + }); + + it('Works with substitution redirect case and a trailing slash', function (){ + const manager = new DynamicRedirectManager({ + permanentMaxAge: 100, + getSubdirectoryURL: (pathname) => { + return urlUtils.urlJoin(urlUtils.getSubdir(), pathname); + } + }); + const from = '^/post/[0-9]+/([a-z0-9\\-]+)'; + const to = '/$1'; + + manager.addRedirect(from , to); + + const req = { + method: 'GET', + url: '/post/10/a-nice-blog-post/' + }; + + let headers = null; + let status = null; + let location = null; + const res = { + set(_headers) { + headers = _headers; + }, + redirect(_status, _location) { + status = _status; + location = _location; + } + }; + + manager.handleRequest(req, res, function next() { + should.fail(true, 'next should NOT have been called'); + }); + + // NOTE: max-age is "0" because it's not a permanent redirect + should.equal(headers['Cache-Control'], 'public, max-age=0'); + should.equal(status, 302); + should.equal(location, '/a-nice-blog-post'); + }); + + it('Redirects keeping the query params for substitution regexp', function (){ + const manager = new DynamicRedirectManager({ + permanentMaxAge: 100, + getSubdirectoryURL: (pathname) => { + return urlUtils.urlJoin(urlUtils.getSubdir(), pathname); + } + }); + + const from = '^/post/[0-9]+/([a-z0-9\\-]+)'; + const to = '/$1'; + + manager.addRedirect(from , to); + + const req = { + method: 'GET', + url: '/post/10/a-nice-blog-post?a=b' + }; + + let headers = null; + let status = null; + let location = null; + const res = { + set(_headers) { + headers = _headers; + }, + redirect(_status, _location) { + status = _status; + location = _location; + } + }; + + manager.handleRequest(req, res, function next() { + should.fail(true, 'next should NOT have been called'); + }); + + // NOTE: max-age is "0" because it's not a permanent redirect + should.equal(headers['Cache-Control'], 'public, max-age=0'); + should.equal(status, 302); + should.equal(location, '/a-nice-blog-post?a=b'); + }); + + it('Redirects keeping the query params', function (){ + const manager = new DynamicRedirectManager({ + permanentMaxAge: 100, + getSubdirectoryURL: (pathname) => { + return urlUtils.urlJoin(urlUtils.getSubdir(), pathname); + } + }); + + const from = '^\\/topic\\/'; + const to = '/'; + + manager.addRedirect(from , to); + + const req = { + method: 'GET', + url: '/topic?something=good' + }; + + let headers = null; + let status = null; + let location = null; + const res = { + set(_headers) { + headers = _headers; + }, + redirect(_status, _location) { + status = _status; + location = _location; + } + }; + + manager.handleRequest(req, res, function next() { + should.fail(true, 'next should NOT have been called'); + }); + + // NOTE: max-age is "0" because it's not a permanent redirect + should.equal(headers['Cache-Control'], 'public, max-age=0'); + should.equal(status, 302); + should.equal(location, '/?something=good'); + }); + }); });