-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Collection and resource ID handling altered to be case-insensitive for issue #49. #51
base: master
Are you sure you want to change the base?
Conversation
Pardon; unexpected differences between Travis' output and my own output have revealed some additional problems. I'll re-open this PR when they're resolved. :) |
Thanks for your contribution. I will give you some feedback in-line. One overarching missing part though (which will hurt existing users) is that this is supposed to be based on how Express has been configured (case sensitive routing vs case insensitive routing). See the original issue for that requirement. |
@@ -108,7 +108,7 @@ class ResponseContext { | |||
url += '/' + encodeURIComponent(id); | |||
} | |||
|
|||
this.addHeader('location', url); | |||
this.addHeader('location', url.toLowerCase()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the incoming URL is case insensitive, why lower case this?
|
||
const reCollection = new RegExp('^' + path + '(\\.[a-zA-Z]+)?/?$'); | ||
const reCollection = new RegExp('^' + path + '(\\.[a-zA-Z]+)?/?$', 'i'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're making this regexp case insensitive, the optional file extension is now double-insensitive.
@@ -21,7 +21,7 @@ class Beer { | |||
} | |||
|
|||
createId() { | |||
this.id = this.name; | |||
this.id = this.name.toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would indicate that every user of this library would always have to make sure that the IDs they generate are lower case, or the system stops working. That doesn't seem very user friendly.
I seem to have misunderstood the original issue discussion. Following the current case sensitivity set in Express would indeed be a friendlier approach, one which I will re-work the contribution to fit. The requirement that users follow a lowercase resource ID scheme within their own resource classes was unintended and will be corrected. This does raise the related issue of what should be treated as a identifier conflict and how such conflict should be prevented/handled. If a resource class's developer is unsure at implementation time as to whether their class will be used in case-sensitive or case-insensitive mode, they must ensure that the IDs their class generates do not depend on case sensitivity. For example, Two main approaches I see are:
The second approach trades away flexibility to buy friendly protection, but removes the point of making case sensitivity configurable at all. The first maintains flexibility but produces a situation where a user may shoot themselves in the foot because Least Surprise suggests case insensitivity in URLs. This is ameliorated somewhat by Express having case insensitivity as the default. I favour the first option, with proper notes in the README. What do you think, @ronkorving? |
I think you're right that our options are limited, and each has its drawbacks. I'm with you, in that option 1 seems preferable. If I understand your approach correctly:
The drawback being you can create conflicting objects (during a first load, we could throw an error on that, insisting that users must fix the files manually) if you change config from case sensitive to insensitive. I'm okay with that drawback. |
Yes, that's a correct summary of the approach. It's turning out much cleaner and friendlier. Since there's going to be some winding back in the next few commits, how about I close this PR, squash my aggregate changes down to a neater set, and then open a new PR so the final history graph is cleaner? |
I discovered a behaviour that seems worth clarifying, as it affects ID integrity and will affect what behaviour tests are written for: During a collection-level PUT, resources that don't already exist are created before being added to the collection map. For example, given a collection PUT of an item that doesn't already exist: The object added to the collection map will instead be: It seems to me that an ID property within a PUT resource should be respected over the collection key that comes with it. (A client should pass a collection where resource IDs and collection keys match, but they might not.) In this case, a PUT of our example: Do you think the current behaviour (ID of created resource during PUT = collection key) should be kept, or changed to prioritise IDs already in submitted resources? |
50e18ec
to
7a660bf
Compare
Rather than closing the PR and opening a new one, feel free to just squash the commits in this PR. I prefer to have the comment history sticking around for other contributors and users so they can understand why decisions have been made the way they have. Regarding IDs,
|
Will do; a squashed version will be force-pushed to this PR's branch. The final should be 4-5 commits long rather than a single squash, as the changes within are easier to read as multiple commits. If I understand the principle of I've currently changed the PUT behaviour to have an in-object |
The old (pre-PR) behavior of PUT should be correct. This PR introduces a read on the |
…for ID case sensitivity to base Collection class, updated test cases to reflect forced lowercase in resource key names.
…ion, GET, HEAD and some POST cases (including a noSubRouter option for testing use with bare Express app). Pulled case sensitivity tests out of method test file. Fixed key names of method & indexes test objects, fixed a method test’s item comparisons to be correct on the basis of the items themselves, regardless of key case sensitivity.
7a660bf
to
c41efd9
Compare
I've reverted the behaviour of PUT to pre-PR and adjusted the case sensitivity tests accordingly. The commits have been squashed to a pleasingly compact set. Of interest: In chasing the very last uncovered line (line 31 of I created a new request function in
I also used an alternative version that hijacked the request socket directly and injected latin1 (binary) data mid-way through the UTF-8 request, and other methods such as aborting the request midway through the body. Express grabs the malformed request error (e.g.
tl;dr I think it'd be safe to remove these lines in
|
Collection ID case insensitivity appears straightforward, requiring that the regular expression in setupRoutes.js have case insensitivity enabled.
However, resource ID case insensitivity requires a little opinionation as to how IDs are stored internally. A possible solution, proposed here, is to opt to store them lowercase, which requires a little adjustment of IDs in the test objects.
New method tests have been added to confirm case insensitivity of collections alone, resources within collections, and collections when resources are being accessed within.