diff --git a/__mocks__/react-native.js b/__mocks__/react-native.js index 26a943ce62bc..006d1aee38af 100644 --- a/__mocks__/react-native.js +++ b/__mocks__/react-native.js @@ -1,7 +1,6 @@ // eslint-disable-next-line no-restricted-imports import * as ReactNative from 'react-native'; import _ from 'underscore'; -import CONST from '../src/CONST'; jest.doMock('react-native', () => { let url = 'https://new.expensify.com/'; @@ -15,7 +14,12 @@ jest.doMock('react-native', () => { // runs against index.native.js source and so anything that is testing a component reliant on withWindowDimensions() // would be most commonly assumed to be on a mobile phone vs. a tablet or desktop style view. This behavior can be // overridden by explicitly setting the dimensions inside a test via Dimensions.set() - let dimensions = CONST.TESTING.SCREEN_SIZE.SMALL; + let dimensions = { + width: 300, + height: 700, + scale: 1, + fontScale: 1, + }; return Object.setPrototypeOf( { diff --git a/package-lock.json b/package-lock.json index 2f821b22cbdd..8fb0d0e6cd2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,6 +96,7 @@ "react-native-screens": "3.21.0", "react-native-svg": "^13.9.0", "react-native-tab-view": "^3.5.2", + "react-native-url-polyfill": "^2.0.0", "react-native-view-shot": "^3.6.0", "react-native-vision-camera": "^2.15.4", "react-native-web-linear-gradient": "^1.1.2", @@ -42906,6 +42907,17 @@ "react-native-pager-view": "*" } }, + "node_modules/react-native-url-polyfill": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-2.0.0.tgz", + "integrity": "sha512-My330Do7/DvKnEvwQc0WdcBnFPploYKp9CYlefDXzIdEaA+PAhDYllkvGeEroEzvc4Kzzj2O4yVdz8v6fjRvhA==", + "dependencies": { + "whatwg-url-without-unicode": "8.0.0-3" + }, + "peerDependencies": { + "react-native": "*" + } + }, "node_modules/react-native-view-shot": { "version": "3.6.0", "license": "MIT", @@ -49479,6 +49491,27 @@ "node": ">=12" } }, + "node_modules/whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "dependencies": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/whatwg-url-without-unicode/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, "node_modules/which": { "version": "2.0.2", "license": "ISC", @@ -79290,6 +79323,14 @@ "use-latest-callback": "^0.1.5" } }, + "react-native-url-polyfill": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/react-native-url-polyfill/-/react-native-url-polyfill-2.0.0.tgz", + "integrity": "sha512-My330Do7/DvKnEvwQc0WdcBnFPploYKp9CYlefDXzIdEaA+PAhDYllkvGeEroEzvc4Kzzj2O4yVdz8v6fjRvhA==", + "requires": { + "whatwg-url-without-unicode": "8.0.0-3" + } + }, "react-native-view-shot": { "version": "3.6.0", "requires": {} @@ -83585,6 +83626,23 @@ "webidl-conversions": "^7.0.0" } }, + "whatwg-url-without-unicode": { + "version": "8.0.0-3", + "resolved": "https://registry.npmjs.org/whatwg-url-without-unicode/-/whatwg-url-without-unicode-8.0.0-3.tgz", + "integrity": "sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==", + "requires": { + "buffer": "^5.4.3", + "punycode": "^2.1.1", + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + } + } + }, "which": { "version": "2.0.2", "requires": { diff --git a/package.json b/package.json index b59414fd2d3b..a7020b692f34 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,7 @@ "react-native-screens": "3.21.0", "react-native-svg": "^13.9.0", "react-native-tab-view": "^3.5.2", + "react-native-url-polyfill": "^2.0.0", "react-native-view-shot": "^3.6.0", "react-native-vision-camera": "^2.15.4", "react-native-web-linear-gradient": "^1.1.2", diff --git a/src/CONFIG.js b/src/CONFIG.js index c5825203db09..e96afec914ac 100644 --- a/src/CONFIG.js +++ b/src/CONFIG.js @@ -80,7 +80,7 @@ export default { }, CAPTURE_METRICS: lodashGet(Config, 'CAPTURE_METRICS', 'false') === 'true', ONYX_METRICS: lodashGet(Config, 'ONYX_METRICS', 'false') === 'true', - DEV_PORT: process.env.PORT || 8080, + DEV_PORT: process.env.PORT || 8082, E2E_TESTING: lodashGet(Config, 'E2E_TESTING', 'false') === 'true', SEND_CRASH_REPORTS: lodashGet(Config, 'SEND_CRASH_REPORTS', 'false') === 'true', IS_USING_WEB_PROXY: getPlatform() === 'web' && useWebProxy, diff --git a/src/CONST.js b/src/CONST.js index a0c6cbf2bcf3..45b35d28ea65 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1311,16 +1311,6 @@ const CONST = { INCORRECT_PASSWORD: 2, }, }, - TESTING: { - SCREEN_SIZE: { - SMALL: { - width: 300, - height: 700, - scale: 1, - fontScale: 1, - }, - }, - }, API_REQUEST_TYPE: { READ: 'read', WRITE: 'write', diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js index 1cc0acf50926..04130e331bac 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/AnchorRenderer.js @@ -15,19 +15,23 @@ import AnchorForAttachmentsOnly from '../../AnchorForAttachmentsOnly'; import * as Url from '../../../libs/Url'; import ROUTES from '../../../ROUTES'; import tryResolveUrlFromApiRoot from '../../../libs/tryResolveUrlFromApiRoot'; +import useEnvironment from '../../../hooks/useEnvironment'; function AnchorRenderer(props) { const htmlAttribs = props.tnode.attributes; - + const {environmentURL} = useEnvironment(); // An auth token is needed to download Expensify chat attachments const isAttachment = Boolean(htmlAttribs[CONST.ATTACHMENT_SOURCE_ATTRIBUTE]); const displayName = lodashGet(props.tnode, 'domNode.children[0].data', ''); const parentStyle = lodashGet(props.tnode, 'parent.styles.nativeTextRet', {}); const attrHref = htmlAttribs.href || ''; - const attrPath = lodashGet(Url.getURLObject(attrHref), 'path', '').replace('/', ''); + const attrPath = Url.getPathFromURL(attrHref); + const hasSameOrigin = Url.hasSameExpensifyOrigin(attrHref, environmentURL); const hasExpensifyOrigin = Url.hasSameExpensifyOrigin(attrHref, CONFIG.EXPENSIFY.EXPENSIFY_URL) || Url.hasSameExpensifyOrigin(attrHref, CONFIG.EXPENSIFY.STAGING_API_ROOT); const internalNewExpensifyPath = - (Url.hasSameExpensifyOrigin(attrHref, CONST.NEW_EXPENSIFY_URL) || Url.hasSameExpensifyOrigin(attrHref, CONST.STAGING_NEW_EXPENSIFY_URL)) && + (Url.hasSameExpensifyOrigin(attrHref, CONST.NEW_EXPENSIFY_URL) || + Url.hasSameExpensifyOrigin(attrHref, CONST.STAGING_NEW_EXPENSIFY_URL) || + attrHref.startsWith(CONST.DEV_NEW_EXPENSIFY_URL)) && !CONST.PATHS_TO_TREAT_AS_EXTERNAL.includes(attrPath) ? attrPath : ''; @@ -48,7 +52,7 @@ function AnchorRenderer(props) { // If we are handling a New Expensify link then we will assume this should be opened by the app internally. This ensures that the links are opened internally via react-navigation // instead of in a new tab or with a page refresh (which is the default behavior of an anchor tag) - if (internalNewExpensifyPath) { + if (internalNewExpensifyPath && hasSameOrigin) { Navigation.navigate(internalNewExpensifyPath); return; } diff --git a/src/libs/Url.js b/src/libs/Url.js index 7e7c230de95f..b64360a7babb 100644 --- a/src/libs/Url.js +++ b/src/libs/Url.js @@ -1,5 +1,4 @@ -import {URL_WEBSITE_REGEX} from 'expensify-common/lib/Url'; - +import 'react-native-url-polyfill/auto'; /** * Add / to the end of any URL if not present * @param {String} url @@ -13,76 +12,43 @@ function addTrailingForwardSlash(url) { } /** - * Parse href to URL object - * @param {String} href - * @returns {Object} + * Get path from URL string + * @param {String} url + * @returns {String} */ -function getURLObject(href) { - const urlRegex = new RegExp(URL_WEBSITE_REGEX, 'gi'); - let match; +function getPathFromURL(url) { try { - if (!href.startsWith('mailto:')) { - match = urlRegex.exec(href); - } - } catch (e) { - // eslint-disable-next-line no-console - console.warn('Error parsing url in Url.getURLObject', {error: e}); - } - if (!match) { - return { - href: undefined, - protocol: undefined, - hostname: undefined, - path: undefined, - }; - } - const baseUrl = match[0]; - const protocol = match[1]; - return { - href, - protocol, - hostname: baseUrl.replace(protocol, ''), - path: href.startsWith(baseUrl) ? href.replace(baseUrl, '') : '', - }; -} - -/** - * Determine if we should remove w3 from hostname - * E.g www.expensify.com should be the same as expensify.com - * @param {String} hostname - * @returns {Boolean} - */ -function shouldRemoveW3FromExpensifyUrl(hostname) { - // Since expensify.com.dev is accessible with and without www subdomain - if (hostname === 'www.expensify.com.dev') { - return true; + const path = new URL(url).pathname; + return path.substring(1); // Remove the leading '/' + } catch (error) { + console.error('Error parsing URL:', error); + return ''; // Return empty string for invalid URLs } - const parts = hostname.split('.').reverse(); - const subDomain = parts[2]; - return subDomain === 'www'; } /** * Determine if two urls have the same origin - * Just care about expensify url to avoid the second-level domain (www.example.co.uk) * @param {String} url1 * @param {String} url2 * @returns {Boolean} */ function hasSameExpensifyOrigin(url1, url2) { - const host1 = getURLObject(url1).hostname; - const host2 = getURLObject(url2).hostname; - if (!host1 || !host2) { + const removeW3 = (host) => host.replace(/^www\./i, ''); + try { + const parsedUrl1 = new URL(url1); + const parsedUrl2 = new URL(url2); + + return removeW3(parsedUrl1.host) === removeW3(parsedUrl2.host); + } catch (error) { + // Handle invalid URLs or other parsing errors + console.error('Error parsing URLs:', error); return false; } - const host1WithoutW3 = shouldRemoveW3FromExpensifyUrl(host1) ? host1.replace('www.', '') : host1; - const host2WithoutW3 = shouldRemoveW3FromExpensifyUrl(host2) ? host2.replace('www.', '') : host2; - return host1WithoutW3 === host2WithoutW3; } export { // eslint-disable-next-line import/prefer-default-export addTrailingForwardSlash, hasSameExpensifyOrigin, - getURLObject, + getPathFromURL, }; diff --git a/tests/unit/UrlTest.js b/tests/unit/UrlTest.js index ea6460e24ca9..7f92f09aeb37 100644 --- a/tests/unit/UrlTest.js +++ b/tests/unit/UrlTest.js @@ -1,221 +1,65 @@ const Url = require('../../src/libs/Url'); describe('Url', () => { - describe('getURLObject()', () => { + describe('getPathFromURL()', () => { it('It should work correctly', () => { - expect(Url.getURLObject('foo.com')).toEqual({ - href: 'foo.com', - protocol: undefined, - hostname: 'foo.com', - path: '', - }); - expect(Url.getURLObject('www.foo.com')).toEqual({ - href: 'www.foo.com', - protocol: undefined, - hostname: 'www.foo.com', - path: '', - }); - expect(Url.getURLObject('http://www.foo.com')).toEqual({ - href: 'http://www.foo.com', - protocol: 'http://', - hostname: 'www.foo.com', - path: '', - }); - expect(Url.getURLObject('http://foo.com/blah_blah')).toEqual({ - href: 'http://foo.com/blah_blah', - protocol: 'http://', - hostname: 'foo.com', - path: '/blah_blah', - }); - expect(Url.getURLObject('http://foo.com/blah_blah_(wikipedia)')).toEqual({ - href: 'http://foo.com/blah_blah_(wikipedia)', - protocol: 'http://', - hostname: 'foo.com', - path: '/blah_blah_(wikipedia)', - }); - expect(Url.getURLObject('http://www.example.com/wpstyle/?p=364')).toEqual({ - href: 'http://www.example.com/wpstyle/?p=364', - protocol: 'http://', - hostname: 'www.example.com', - path: '/wpstyle/?p=364', - }); - expect(Url.getURLObject('https://www.example.com/foo/?bar=baz&inga=42&quux')).toEqual({ - href: 'https://www.example.com/foo/?bar=baz&inga=42&quux', - protocol: 'https://', - hostname: 'www.example.com', - path: '/foo/?bar=baz&inga=42&quux', - }); - expect(Url.getURLObject('http://foo.com/(something)?after=parens')).toEqual({ - href: 'http://foo.com/(something)?after=parens', - protocol: 'http://', - hostname: 'foo.com', - path: '/(something)?after=parens', - }); - expect(Url.getURLObject('http://code.google.com/events/#&product=browser')).toEqual({ - href: 'http://code.google.com/events/#&product=browser', - protocol: 'http://', - hostname: 'code.google.com', - path: '/events/#&product=browser', - }); - expect(Url.getURLObject('http://foo.bar/?q=Test%20URL-encoded%20stuff')).toEqual({ - href: 'http://foo.bar/?q=Test%20URL-encoded%20stuff', - protocol: 'http://', - hostname: 'foo.bar', - path: '/?q=Test%20URL-encoded%20stuff', - }); - expect(Url.getURLObject('http://www.test.com/path?param=123#123')).toEqual({ - href: 'http://www.test.com/path?param=123#123', - protocol: 'http://', - - hostname: 'www.test.com', - path: '/path?param=123#123', - }); - expect(Url.getURLObject('http://1337.net')).toEqual({ - href: 'http://1337.net', - protocol: 'http://', - - hostname: '1337.net', - path: '', - }); - expect(Url.getURLObject('http://a.b-c.de/')).toEqual({ - href: 'http://a.b-c.de/', - protocol: 'http://', - - hostname: 'a.b-c.de', - path: '/', - }); - expect(Url.getURLObject('https://sd1.sd2.docs.google.com/')).toEqual({ - href: 'https://sd1.sd2.docs.google.com/', - protocol: 'https://', - hostname: 'sd1.sd2.docs.google.com', - path: '/', - }); - expect(Url.getURLObject('https://expensify.cash/#/r/1234')).toEqual({ - href: 'https://expensify.cash/#/r/1234', - protocol: 'https://', - hostname: 'expensify.cash', - path: '/#/r/1234', - }); - expect(Url.getURLObject('https://github.com/Expensify/ReactNativeChat/pull/6.45')).toEqual({ - href: 'https://github.com/Expensify/ReactNativeChat/pull/6.45', - protocol: 'https://', - hostname: 'github.com', - path: '/Expensify/ReactNativeChat/pull/6.45', - }); - expect(Url.getURLObject('https://github.com/Expensify/Expensify/issues/143,231')).toEqual({ - href: 'https://github.com/Expensify/Expensify/issues/143,231', - protocol: 'https://', - hostname: 'github.com', - path: '/Expensify/Expensify/issues/143,231', - }); - expect(Url.getURLObject('testRareTLDs.beer')).toEqual({ - href: 'testRareTLDs.beer', - protocol: undefined, - hostname: 'testRareTLDs.beer', - path: '', - }); - expect(Url.getURLObject('test@expensify.com')).toEqual({ - href: 'test@expensify.com', - protocol: undefined, - hostname: 'expensify.com', - path: '', - }); - expect(Url.getURLObject('test.completelyFakeTLD')).toEqual({ - href: undefined, - protocol: undefined, - hostname: undefined, - path: undefined, - }); + expect(Url.getPathFromURL('http://www.foo.com')).toEqual(''); + expect(Url.getPathFromURL('http://foo.com/blah_blah')).toEqual('blah_blah'); + expect(Url.getPathFromURL('http://foo.com/blah_blah_(wikipedia)')).toEqual('blah_blah_(wikipedia)'); + expect(Url.getPathFromURL('http://www.example.com/wpstyle/?p=364')).toEqual('wpstyle/'); + expect(Url.getPathFromURL('https://www.example.com/foo/?bar=baz&inga=42&quux')).toEqual('foo/'); + expect(Url.getPathFromURL('http://foo.com/(something)?after=parens')).toEqual('(something)'); + expect(Url.getPathFromURL('http://code.google.com/events/#&product=browser')).toEqual('events/'); + expect(Url.getPathFromURL('http://foo.bar/?q=Test%20URL-encoded%20stuff')).toEqual(''); + expect(Url.getPathFromURL('http://www.test.com/path?param=123#123')).toEqual('path'); + expect(Url.getPathFromURL('http://1337.net')).toEqual(''); + expect(Url.getPathFromURL('http://a.b-c.de/')).toEqual(''); + expect(Url.getPathFromURL('https://sd1.sd2.docs.google.com/')).toEqual(''); + expect(Url.getPathFromURL('https://expensify.cash/#/r/1234')).toEqual(''); + expect(Url.getPathFromURL('https://github.com/Expensify/ReactNativeChat/pull/6.45')).toEqual('Expensify/ReactNativeChat/pull/6.45'); + expect(Url.getPathFromURL('https://github.com/Expensify/Expensify/issues/143,231')).toEqual('Expensify/Expensify/issues/143,231'); + expect(Url.getPathFromURL('testRareTLDs.beer')).toEqual(''); + expect(Url.getPathFromURL('test@expensify.com')).toEqual(''); + expect(Url.getPathFromURL('test.completelyFakeTLD')).toEqual(''); expect( - Url.getURLObject( + Url.getPathFromURL( // eslint-disable-next-line max-len 'https://www.expensify.com/_devportal/tools/logSearch/#query=request_id:(%22Ufjjim%22)+AND+timestamp:[2021-01-08T03:48:10.389Z+TO+2021-01-08T05:48:10.389Z]&index=logs_expensify-008878)', ), - ).toEqual({ - // eslint-disable-next-line max-len - href: 'https://www.expensify.com/_devportal/tools/logSearch/#query=request_id:(%22Ufjjim%22)+AND+timestamp:[2021-01-08T03:48:10.389Z+TO+2021-01-08T05:48:10.389Z]&index=logs_expensify-008878)', - protocol: 'https://', - hostname: 'www.expensify.com', - path: '/_devportal/tools/logSearch/#query=request_id:(%22Ufjjim%22)+AND+timestamp:[2021-01-08T03:48:10.389Z+TO+2021-01-08T05:48:10.389Z]&index=logs_expensify-008878)', - }); - expect(Url.getURLObject('http://necolas.github.io/react-native-web/docs/?path=/docs/components-pressable--disabled ')).toEqual({ - href: 'http://necolas.github.io/react-native-web/docs/?path=/docs/components-pressable--disabled ', - protocol: 'http://', - hostname: 'necolas.github.io', - path: '/react-native-web/docs/?path=/docs/components-pressable--disabled ', - }); - expect(Url.getURLObject('https://github.com/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ')).toEqual({ - href: 'https://github.com/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ', - protocol: 'https://', - hostname: 'github.com', - path: '/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ', - }); - expect(Url.getURLObject('https://github.com/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ')).toEqual({ - href: 'https://github.com/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ', - protocol: 'https://', - hostname: 'github.com', - path: '/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ', - }); - expect(Url.getURLObject('mm..food ')).toEqual({ - href: undefined, - protocol: undefined, - hostname: undefined, - path: undefined, - }); - expect(Url.getURLObject('upwork.com/jobs/~016781e062ce860b84 ')).toEqual({ - href: 'upwork.com/jobs/~016781e062ce860b84 ', - protocol: undefined, - hostname: 'upwork.com', - path: '/jobs/~016781e062ce860b84 ', - }); + ).toEqual('_devportal/tools/logSearch/'); + expect(Url.getPathFromURL('http://necolas.github.io/react-native-web/docs/?path=/docs/components-pressable--disabled ')).toEqual('react-native-web/docs/'); + expect(Url.getPathFromURL('https://github.com/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ')).toEqual('Expensify/Expensify.cash/issues/123'); + expect(Url.getPathFromURL('https://github.com/Expensify/Expensify.cash/issues/123#:~:text=Please%20work/Expensify.cash ')).toEqual('Expensify/Expensify.cash/issues/123'); + expect(Url.getPathFromURL('mm..food ')).toEqual(''); + expect(Url.getPathFromURL('https://upwork.com/jobs/~016781e062ce860b84 ')).toEqual('jobs/~016781e062ce860b84'); expect( - Url.getURLObject( + Url.getPathFromURL( // eslint-disable-next-line max-len "https://bastion1.sjc/logs/app/kibana#/discover?_g=()&_a=(columns:!(_source),index:'2125cbe0-28a9-11e9-a79c-3de0157ed580',interval:auto,query:(language:lucene,query:''),sort:!(timestamp,desc))", ), - ).toEqual({ - // eslint-disable-next-line max-len - href: "https://bastion1.sjc/logs/app/kibana#/discover?_g=()&_a=(columns:!(_source),index:'2125cbe0-28a9-11e9-a79c-3de0157ed580',interval:auto,query:(language:lucene,query:''),sort:!(timestamp,desc))", - protocol: 'https://', - - hostname: 'bastion1.sjc', - // eslint-disable-next-line max-len - path: "/logs/app/kibana#/discover?_g=()&_a=(columns:!(_source),index:'2125cbe0-28a9-11e9-a79c-3de0157ed580',interval:auto,query:(language:lucene,query:''),sort:!(timestamp,desc))", - }); - expect(Url.getURLObject("google.com/maps/place/The+Flying'+Saucer/@42.4043314,-86.2742418,15z/data=!4m5!3m4!1s0x0:0xe28f6108670216bc!8m2!3d42.4043316!4d-86.2742121")).toEqual({ - href: "google.com/maps/place/The+Flying'+Saucer/@42.4043314,-86.2742418,15z/data=!4m5!3m4!1s0x0:0xe28f6108670216bc!8m2!3d42.4043316!4d-86.2742121", - protocol: undefined, - hostname: 'google.com', - path: "/maps/place/The+Flying'+Saucer/@42.4043314,-86.2742418,15z/data=!4m5!3m4!1s0x0:0xe28f6108670216bc!8m2!3d42.4043316!4d-86.2742121", - }); + ).toEqual('logs/app/kibana'); + expect( + Url.getPathFromURL("https://google.com/maps/place/The+Flying'+Saucer/@42.4043314,-86.2742418,15z/data=!4m5!3m4!1s0x0:0xe28f6108670216bc!8m2!3d42.4043316!4d-86.2742121"), + ).toEqual("maps/place/The+Flying'+Saucer/@42.4043314,-86.2742418,15z/data=!4m5!3m4!1s0x0:0xe28f6108670216bc!8m2!3d42.4043316!4d-86.2742121"); expect( - Url.getURLObject( + Url.getPathFromURL( // eslint-disable-next-line max-len - 'google.com/maps/place/%E9%9D%92%E5%B3%B6%E9%80%A3%E7%B5%A1%E8%88%B9%E4%B9%97%E5%A0%B4/@33.7363156,132.4877213,17.78z/data=!4m5!3m4!1s0x3545615c8c65bf7f:0xb89272c1a705a33f!8m2!3d33.7366776!4d132.4878843 ', + 'https://google.com/maps/place/%E9%9D%92%E5%B3%B6%E9%80%A3%E7%B5%A1%E8%88%B9%E4%B9%97%E5%A0%B4/@33.7363156,132.4877213,17.78z/data=!4m5!3m4!1s0x3545615c8c65bf7f:0xb89272c1a705a33f!8m2!3d33.7366776!4d132.4878843 ', ), - ).toEqual({ - // eslint-disable-next-line max-len - href: 'google.com/maps/place/%E9%9D%92%E5%B3%B6%E9%80%A3%E7%B5%A1%E8%88%B9%E4%B9%97%E5%A0%B4/@33.7363156,132.4877213,17.78z/data=!4m5!3m4!1s0x3545615c8c65bf7f:0xb89272c1a705a33f!8m2!3d33.7366776!4d132.4878843 ', - protocol: undefined, - hostname: 'google.com', - // eslint-disable-next-line max-len - path: '/maps/place/%E9%9D%92%E5%B3%B6%E9%80%A3%E7%B5%A1%E8%88%B9%E4%B9%97%E5%A0%B4/@33.7363156,132.4877213,17.78z/data=!4m5!3m4!1s0x3545615c8c65bf7f:0xb89272c1a705a33f!8m2!3d33.7366776!4d132.4878843 ', - }); + ).toEqual( + 'maps/place/%E9%9D%92%E5%B3%B6%E9%80%A3%E7%B5%A1%E8%88%B9%E4%B9%97%E5%A0%B4/@33.7363156,132.4877213,17.78z/data=!4m5!3m4!1s0x3545615c8c65bf7f:0xb89272c1a705a33f!8m2!3d33.7366776!4d132.4878843', + ); expect( - Url.getURLObject( + Url.getPathFromURL( // eslint-disable-next-line max-len 'https://www.google.com/maps/place/Taj+Mahal+@is~"Awesome"/@27.1751496,78.0399535,17z/data=!4m12!1m6!3m5!1s0x39747121d702ff6d:0xdd2ae4803f767dde!2sTaj+Mahal!8m2!3d27.1751448!4d78.0421422!3m4!1s0x39747121d702ff6d:0xdd2ae4803f767dde!8m2!3d27.1751448!4d78.0421422', ), - ).toEqual({ - // eslint-disable-next-line max-len - href: 'https://www.google.com/maps/place/Taj+Mahal+@is~"Awesome"/@27.1751496,78.0399535,17z/data=!4m12!1m6!3m5!1s0x39747121d702ff6d:0xdd2ae4803f767dde!2sTaj+Mahal!8m2!3d27.1751448!4d78.0421422!3m4!1s0x39747121d702ff6d:0xdd2ae4803f767dde!8m2!3d27.1751448!4d78.0421422', - protocol: 'https://', - hostname: 'www.google.com', - // eslint-disable-next-line max-len - path: '/maps/place/Taj+Mahal+@is~"Awesome"/@27.1751496,78.0399535,17z/data=!4m12!1m6!3m5!1s0x39747121d702ff6d:0xdd2ae4803f767dde!2sTaj+Mahal!8m2!3d27.1751448!4d78.0421422!3m4!1s0x39747121d702ff6d:0xdd2ae4803f767dde!8m2!3d27.1751448!4d78.0421422', - }); + ).toEqual( + 'maps/place/Taj+Mahal+@is~%22Awesome%22/@27.1751496,78.0399535,17z/data=!4m12!1m6!3m5!1s0x39747121d702ff6d:0xdd2ae4803f767dde!2sTaj+Mahal!8m2!3d27.1751448!4d78.0421422!3m4!1s0x39747121d702ff6d:0xdd2ae4803f767dde!8m2!3d27.1751448!4d78.0421422', + ); }); }); + describe('hasSameExpensifyOrigin()', () => { describe('happy path', () => { it('It should work correctly', () => { @@ -224,8 +68,8 @@ describe('Url', () => { it('It should work correctly with www in both urls', () => { expect(Url.hasSameExpensifyOrigin('https://www.new.expensify.com/inbox/124', 'https://www.new.expensify.com/action/123')).toBe(true); }); - it('It should work correctly without https://', () => { - expect(Url.hasSameExpensifyOrigin('new.expensify.com/action/1234', 'new.expensify.com/action/123')).toBe(true); + it('It should work correctly with www in one of two urls', () => { + expect(Url.hasSameExpensifyOrigin('https://new.expensify.com/action/1234', 'https://www.new.expensify.com/action/123')).toBe(true); }); it('It should work correctly with old dot', () => { expect(Url.hasSameExpensifyOrigin('https://expensify.com/action/123', 'https://www.expensify.com/action/123')).toBe(true); @@ -244,9 +88,6 @@ describe('Url', () => { it('It should work correctly with www', () => { expect(Url.hasSameExpensifyOrigin('https://expensify.com/action/1234', 'https://www.new.expensify.com/action/123')).toBe(false); }); - it('It should work correctly with www in one of two urls', () => { - expect(Url.hasSameExpensifyOrigin('https://new.expensify.com/action/1234', 'https://www.new.expensify.com/action/123')).toBe(false); - }); }); }); });