Skip to content

fix: case-sensitive routing for sub-router mounting points (#17) - #24

Merged
jthomerson merged 1 commit into
silvermine:masterfrom
yokuze:sub_router_case_sensitivity_17
Mar 24, 2019
Merged

jthomerson merged 1 commit into
silvermine:masterfrom
yokuze:sub_router_case_sensitivity_17

Conversation

@yokuze

@yokuze yokuze commented Mar 1, 2019

Copy link
Copy Markdown
Contributor

When a sub-router was mounted to a given path, the
SubRouterProcessorChain did not respect the router's case-sensitivity
settings. Additionally, sub-routers should NOT inherit their
case-sensitivity settings from their parent router.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage decreased (-0.002%) to 99.121% when pulling aacfc53 on yokuze:sub_router_case_sensitivity_17 into c625d58 on silvermine:master.

@coveralls

coveralls commented Mar 1, 2019 •

Copy link
Copy Markdown

Coverage Status

Coverage decreased (-0.001%) to 99.145% when pulling d7dfe46 on yokuze:sub_router_case_sensitivity_17 into c739611 on silvermine:master.

Comment thread src/Router.ts
// routes are created (technically the `IRequestMatchingProcessorChain` objects, in
// particular `RouteMatchingProcessorChain`), the case sensitivity is already set
// (inherited from the router that created the chain).
router.routerOptions.caseSensitive = this.routerOptions.caseSensitive;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to test what happens when a router is added to an app

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified this using the following test case:

const express = require('express'),
      port = 3000,
      app = express();

// Test request: GET /World
// The 'case sensitive routing' application setting is NOT passed on to routers
// registered with app.use

const router = express.Router();

app.set('case sensitive routing', true);
app.use(router); // set this BEFORE adding any routes

router.get('/World', (req, resp, next) => {
   console.log('uppercase /World');
   console.log('subApp is case sens?', subApp.get('case sensitive routing'));
   next();
});
router.get('/world', (req, resp, next) => {
   console.log('lowercase /world');
   console.log('subApp is case sens?', subApp.get('case sensitive routing'));
   next();
});
router.get('*', (req, resp) => { resp.send('world'); });

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

@yokuze

yokuze commented Mar 1, 2019

Copy link
Copy Markdown
Contributor Author

After my response to your one comment, this is ready for re-review.

Comment thread tests/integration-tests.test.ts Outdated
let handler = spy((_req: Request, _resp: Response, next: NextCallback) => { next(); });

// Case-sensitive routing should be *off* for the sub-router, but we turn
// case-sensitive routing *on* for the parent router (app) so that we know that

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording could be simpler:

App (parent, `/hello`): case-sensitive
Router (`/world`): case-insensitive

Comment thread tests/integration-tests.test.ts Outdated
app.enable('case sensitive routing');
expect(app.routerOptions.caseSensitive).to.eql(true);

// `/hello/world` is case-insensitive

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment clarification or removal.

Comment thread tests/integration-tests.test.ts Outdated
app.addSubRouter('/hello', router);
router.get('/world', handler);

// Return a response

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ADIRL, let's return a not found response or something that makes it easier to read the test - the outcome is either that it matched ("Hello world") or that it did not match ("not found"). It's confusing for non-matching tests below to say "hello world".

Comment thread tests/integration-tests.test.ts Outdated
// Disable case-sensitive routing
const router = new Router({ caseSensitive: false });

let handler = spy((_req: Request, _resp: Response, next: NextCallback) => { next(); });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as commented on below. this is the place that should say resp.send('hello world')

Comment thread tests/integration-tests.test.ts Outdated
handler.resetHistory();

testOutcome('GET', '/HELLO/world', 'Hello world');
assert.calledOnce(handler);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me at all if we're doing the same thing as Express here. Here's a sample using Express. The parent (/hello) portion of the URL maintains its case sensitivity even though the rest of the URL (the /world) part is not case sensitive.

Express example:

const express = require('express'),
      port = 3000,
      app = express();

// Test request: GET /World
// The 'case sensitive routing' application setting is NOT passed on to routers
// registered with app.use

const router = express.Router({ caseSensitive: false }); 

app.enable('case sensitive routing');

app.use('/hello', router);
router.get('/world', (req, resp) => { resp.send('Hello world'); }); 

app.use((req, resp) => { resp.send('not found'); }); 

app.listen(port, () => console.log(`Example app listening on port ${port}!`));

Expected outcomes:

'/hello/world' => 'hello world'
'/hello/WORLD' => 'hello world'
'/HELLO/WORLD' => 'not found'
'/goodbye/world' => 'not found (hanging spider)'

Comment thread tests/integration-tests.test.ts Outdated

handler = spy((_req: Request, _resp: Response, next: NextCallback) => { next(); });

// `/Hello/world` is case-sensitive

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comments on this test (also, this comment is unclear).

@yokuze
yokuze force-pushed the sub_router_case_sensitivity_17 branch from aacfc53 to dcc622e Compare March 15, 2019 20:47
@yokuze

yokuze commented Mar 15, 2019

Copy link
Copy Markdown
Contributor Author

Great feedback, thank you. After fixing the wording of the tests and associated comments, I saw that I had indeed implemented this incorrectly. Thank you!

…e#17)

When a sub-router was mounted to a given path, the
SubRouterProcessorChain did not respect the router's case-sensitivity
settings. Additionally, sub-routers should NOT inherit their
case-sensitivity settings from their parent router.
@yokuze
yokuze force-pushed the sub_router_case_sensitivity_17 branch from dcc622e to d7dfe46 Compare March 18, 2019 13:11
@yokuze

yokuze commented Mar 18, 2019

Copy link
Copy Markdown
Contributor Author

Ok, this should be good for re-review. I also added a comment to the SubRouterProcessorChain constructor to document the reason for using the parent router's case-sensitivity setting when matching the mounting point path.

@jthomerson

Copy link
Copy Markdown
Member

image

I love how you still get penalized in this codebase for a PR that has a net reduction in the lines of code. 😆

@jthomerson
jthomerson merged commit a7b2af1 into silvermine:master Mar 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants