Skip to content

Commit

Permalink
Merge pull request #236 from namecheap/fix/matching-routes-with-trail…
Browse files Browse the repository at this point in the history
…ing-slash-at-the-end

fix: add routes matching when a route has `/` at the end
  • Loading branch information
oleh-momot authored Jan 4, 2021
2 parents d43c0ed + 4673f77 commit 2e84e57
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 3 deletions.
10 changes: 9 additions & 1 deletion ilc/common/router/Router.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,20 @@ module.exports = class Router {

if (v.route === '*') {
routeExp = new RegExp(`(.*)`);
} else if (v.route === '/') {
routeExp = new RegExp(`^(/)$`);
} else if (v.route.match(/\/\*$/) !== null) {
const basePath = route.substring(0, route.length - 3);

routeExp = new RegExp(`^(${basePath})/?.*`);
} else {
routeExp = new RegExp(`^(${route})$`);
let basePath = route;

if (v.route[v.route.length - 1] === '/') {
basePath = route.substring(0, route.length - 1);
};

routeExp = new RegExp(`^(${basePath})/?$`);
}

return {
Expand Down
116 changes: 114 additions & 2 deletions ilc/common/router/Router.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const chai = require('chai');
const Router = require('./Router');

describe('router', () => {
const registryConfig = {
const registryConfig = Object.freeze({
routes: [
{
routeId: 'commonRoute',
Expand Down Expand Up @@ -93,7 +93,7 @@ describe('router', () => {
},
},
},
};
});

describe('.match()', function () {
it('should throw an error when 404 special route does not exist', () => {
Expand Down Expand Up @@ -160,6 +160,118 @@ describe('router', () => {
},
});
});

describe('when a route has `/` at the end', () => {
const routeThatHasTrailingSlashAtTheEnd = Object.freeze({
routeId: 'launchpadRoute',
route: '/launchpad/',
next: false,
template: 'launchpadTemplate',
slots: {
launchpad: {
appName: 'launchpad',
props: {
firstHeroSlotProp: 'firstLaunchpadSlotProp',
secondHeroSlotProp: 'secondLaunchpadSlotProp',
},
kind: 'primary',
},
},
});

const registryConfigWithRouteThatHasTrailingSlashAtTheEnd = Object.freeze({
...registryConfig,
routes: [
routeThatHasTrailingSlashAtTheEnd,
...registryConfig.routes
],
});

it('should return a matched route by a request url that does not have `/` at the end', () => {
const router = new Router(registryConfigWithRouteThatHasTrailingSlashAtTheEnd);
const reqUrlThatDoesNotHaveTrailingSlashAtTheEnd = '/launchpad';

chai.expect(router.match(reqUrlThatDoesNotHaveTrailingSlashAtTheEnd)).to.be.eql({
routeId: 'launchpadRoute',
route: '/launchpad/',
basePath: '/launchpad',
reqUrl: reqUrlThatDoesNotHaveTrailingSlashAtTheEnd,
template: 'launchpadTemplate',
specialRole: null,
slots: routeThatHasTrailingSlashAtTheEnd.slots,
});
});

it('should return a matched route by a request url that has `/` at the end', () => {
const router = new Router(registryConfigWithRouteThatHasTrailingSlashAtTheEnd);
const reqUrlThatHasTrailingSlashAtTheEnd = '/launchpad/';

chai.expect(router.match(reqUrlThatHasTrailingSlashAtTheEnd)).to.be.eql({
routeId: 'launchpadRoute',
route: '/launchpad/',
basePath: '/launchpad',
reqUrl: reqUrlThatHasTrailingSlashAtTheEnd,
template: 'launchpadTemplate',
specialRole: null,
slots: routeThatHasTrailingSlashAtTheEnd.slots,
});
});

it('should return a matched route when a requested url is `/`', () => {
const routeThatEqualsTrailingSlash = Object.freeze({
routeId: 'homeRoute',
route: '/',
next: false,
template: 'homeTemplate',
slots: {
home: {
appName: 'home',
props: {
firstHomeSlotProp: 'firstHomeSlotProp',
secondHomeSlotProp: 'secondHomeSlotProp',
},
kind: 'primary',
},
},
});
const registryConfigThatHasRouteThatEqualsTrailingSlash = Object.freeze({
...registryConfig,
routes: [
routeThatEqualsTrailingSlash,
...registryConfig.routes,
],
});
const router = new Router(registryConfigThatHasRouteThatEqualsTrailingSlash);
const reqUrl = '/';

chai.expect(router.match(reqUrl)).to.be.eql({
routeId: 'homeRoute',
route: '/',
basePath: '/',
reqUrl,
template: 'homeTemplate',
specialRole: null,
slots: routeThatEqualsTrailingSlash.slots,
});
});

it('should return 404 route when a router does not match a route by a requested url that has something after `/`', () => {
const router = new Router(registryConfigWithRouteThatHasTrailingSlashAtTheEnd);
const reqUrl = '/launchpad/something';

chai.expect(router.match(reqUrl)).to.be.eql({
routeId: 'errorsRoute',
route: '/404',
basePath: '/',
reqUrl,
template: 'errorsTemplate',
specialRole: 404,
slots: {
...registryConfigWithRouteThatHasTrailingSlashAtTheEnd.specialRoutes['404'].slots,
},
});
});
});
});

describe('.matchSpecial()', function () {
Expand Down

0 comments on commit 2e84e57

Please sign in to comment.