diff --git a/lib/units/validateURI.js b/lib/units/validateURI.js index 048115f4..7f769c11 100644 --- a/lib/units/validateURI.js +++ b/lib/units/validateURI.js @@ -1,41 +1,22 @@ +const url = require('url'); const deepEqual = require('deep-equal'); const APIARY_URI_TYPE = 'text/vnd.apiary.uri'; /** - * Parses a given query string into an Object. - * @param {string} queryString - * @returns {Object} - */ -const parseQueryString = (queryString) => { - if (!queryString) { - return {}; - } - - return queryString.split('&').reduce((acc, paramString) => { - const [paramName, paramValue] = paramString.split('='); - const nextValue = Object.prototype.hasOwnProperty.call(acc, paramName) - ? [].concat(acc[paramName], paramValue) - : paramValue; - - return { - ...acc, - [paramName]: nextValue - }; - }, {}); -}; - -/** + * Parses the given URI and returns the properties + * elligible for comparison. Leaves out raw properties like "path" + * that cannot be compared due to struct query parameters order. * @param {string} uri + * @returns {Object} */ const parseURI = (uri) => { - const parsed = /(\w+)(\?(.+))?/.exec(uri) || []; - const hostname = parsed[1]; - const queryString = parsed[3]; - + const { pathname, port, hash, query } = url.parse(uri, true); return { - hostname, - query: parseQueryString(queryString) + pathname, + port, + hash, + query }; }; @@ -43,10 +24,11 @@ const validateURI = (expected, real) => { const { uri: expectedURI } = expected; const { uri: realURI } = real; - // Parses URI into Objects to deal with - // the order of query parameters. - const parsedExpected = parseURI(expectedURI); - const parsedReal = parseURI(realURI); + // Parses URI to perform a correct comparison: + // - literal comparison of pathname + // - order-insensitive comparison of query parameters + const parsedExpected = parseURI(expectedURI, true); + const parsedReal = parseURI(realURI, true); // Note the different order of arguments between // "validateURI" and "deepEqual".