|
| 1 | +const url = require('url'); |
1 | 2 | const deepEqual = require('deep-equal');
|
2 | 3 |
|
3 | 4 | const APIARY_URI_TYPE = 'text/vnd.apiary.uri';
|
4 | 5 |
|
5 | 6 | /**
|
6 |
| - * Parses a given query string into an Object. |
7 |
| - * @param {string} queryString |
8 |
| - * @returns {Object<string, string | string[]>} |
9 |
| - */ |
10 |
| -const parseQueryString = (queryString) => { |
11 |
| - if (!queryString) { |
12 |
| - return {}; |
13 |
| - } |
14 |
| - |
15 |
| - return queryString.split('&').reduce((acc, paramString) => { |
16 |
| - const [paramName, paramValue] = paramString.split('='); |
17 |
| - const nextValue = Object.prototype.hasOwnProperty.call(acc, paramName) |
18 |
| - ? [].concat(acc[paramName], paramValue) |
19 |
| - : paramValue; |
20 |
| - |
21 |
| - return { |
22 |
| - ...acc, |
23 |
| - [paramName]: nextValue |
24 |
| - }; |
25 |
| - }, {}); |
26 |
| -}; |
27 |
| - |
28 |
| -/** |
| 7 | + * Parses the given URI and returns the properties |
| 8 | + * elligible for comparison. Leaves out raw properties like "path" |
| 9 | + * that cannot be compared due to struct query parameters order. |
29 | 10 | * @param {string} uri
|
| 11 | + * @returns {Object<string, string | number>} |
30 | 12 | */
|
31 | 13 | const parseURI = (uri) => {
|
32 |
| - const parsed = /(\w+)(\?(.+))?/.exec(uri) || []; |
33 |
| - const hostname = parsed[1]; |
34 |
| - const queryString = parsed[3]; |
35 |
| - |
| 14 | + const { pathname, port, hash, query } = url.parse(uri, true); |
36 | 15 | return {
|
37 |
| - hostname, |
38 |
| - query: parseQueryString(queryString) |
| 16 | + pathname, |
| 17 | + port, |
| 18 | + hash, |
| 19 | + query |
39 | 20 | };
|
40 | 21 | };
|
41 | 22 |
|
42 | 23 | const validateURI = (expected, real) => {
|
43 | 24 | const { uri: expectedURI } = expected;
|
44 | 25 | const { uri: realURI } = real;
|
45 | 26 |
|
46 |
| - // Parses URI into Objects to deal with |
47 |
| - // the order of query parameters. |
48 |
| - const parsedExpected = parseURI(expectedURI); |
49 |
| - const parsedReal = parseURI(realURI); |
| 27 | + // Parses URI to perform a correct comparison: |
| 28 | + // - literal comparison of pathname |
| 29 | + // - order-insensitive comparison of query parameters |
| 30 | + const parsedExpected = parseURI(expectedURI, true); |
| 31 | + const parsedReal = parseURI(realURI, true); |
50 | 32 |
|
51 | 33 | // Note the different order of arguments between
|
52 | 34 | // "validateURI" and "deepEqual".
|
|
0 commit comments