UNPKG

@plone/volto

Version:
537 lines (512 loc) 18.3 kB
import config from '@plone/volto/registry'; import { flattenToAppURL, flattenHTMLToAppURL, stripQuerystring, toPublicURL, getBaseUrl, getView, isCmsUi, isInternalURL, isUrl, getFieldURL, normalizeUrl, removeProtocol, addAppURL, expandToBackendURL, checkAndNormalizeUrl, normaliseMail, normalizeTelephone, flattenScales, } from './Url'; beforeEach(() => { config.settings.legacyTraverse = false; }); const { settings } = config; describe('Url', () => { describe('getBaseUrl', () => { it('can remove a view name from an absolute url', () => { expect(getBaseUrl('http://localhost/edit')).toBe('http://localhost'); }); it('can remove a view name from a relative url', () => { expect(getBaseUrl('/contents')).toBe(''); }); it('can remove a view name from a relative url', () => { expect(getBaseUrl('/edit')).toBe(''); }); it('can remove a view name from a relative url', () => { expect(getBaseUrl('/register')).toBe(''); }); it('can remove a view name from a relative url', () => { expect(getBaseUrl('/passwordreset')).toBe(''); }); it('can remove a view name from a relative url', () => { expect(getBaseUrl('/passwordreset/token')).toBe(''); }); it('can remove a view name from a controlpanel url', () => { expect(getBaseUrl('/controlpanel/date-time')).toBe(''); }); it('it does not match inner parts, only last ones', () => { expect(getBaseUrl('/bla/doh/history/doh/bla')).toBe( '/bla/doh/history/doh/bla', ); }); it('it does not match inner parts, only last ones II', () => { expect(getBaseUrl('/bla/doh/sharing-my-test/doh/bla')).toBe( '/bla/doh/sharing-my-test/doh/bla', ); }); it('does nothing if no url is undefined', () => { expect(getBaseUrl(undefined)).toBe(undefined); }); it('return empty string if no url is empty string', () => { expect(getBaseUrl('')).toBe(''); }); it('return a null/undefined mailto address ', () => { expect(normaliseMail(null)).toBe('mailto:null'); expect(normaliseMail(undefined)).toBe('mailto:undefined'); }); it('return a null/undefined telephone number', () => { expect(normalizeTelephone(null)).toBe('tel:null'); expect(normalizeTelephone(undefined)).toBe('tel:undefined'); }); it('null returns an invalid link', () => { expect(checkAndNormalizeUrl(null).isValid).toBe(false); }); }); describe('getView', () => { it('can get the edit view from the url', () => { expect(getView('http://localhost/edit')).toBe('edit'); }); it('can get the view view from the url', () => { expect(getView('http://localhost/my-blog')).toBe('view'); }); }); describe('flattenToAppURL', () => { it('flattens a given URL to the app URL', () => { expect(flattenToAppURL(`${settings.apiPath}/edit`)).toBe('/edit'); }); it('does not fail if url is undefined', () => { expect(flattenToAppURL()).toBe(undefined); }); it('flattens a given URL to the app URL, with settings.internalApiPath', () => { const url = 'http://plone:8080/Plone/something'; const saved = settings.internalApiPath; settings.internalApiPath = 'http://plone:8080/Plone'; expect(flattenToAppURL(url)).toBe('/something'); settings.internalApiPath = saved; }); }); describe('stripQuerystring', () => { it('returns stripped URL given a URL with a querystring', () => { expect(stripQuerystring('/content?search=test')).toBe('/content'); }); }); describe('toPublicURL', () => { it('returns public URL given the app URL', () => { const savedPublicURL = settings.publicURL; settings.publicURL = 'https://plone.org'; expect(toPublicURL('/section/content')).toBe( 'https://plone.org/section/content', ); settings.publicURL = savedPublicURL; }); it('returns public URL given the content @id while in dev mode', () => { const savedPublicURL = settings.publicURL; const savedApiPath = settings.apiPath; settings.publicURL = 'https://plone.org'; settings.apiPath = 'http://localhost:3000/api'; expect(toPublicURL('http://localhost:3000/api/section/content')).toBe( 'https://plone.org/section/content', ); settings.publicURL = savedPublicURL; settings.apiPath = savedApiPath; }); it('returns public URL given the content @id while in dev mode', () => { const savedPublicURL = settings.publicURL; const savedApiPath = settings.apiPath; settings.publicURL = 'https://plone.org'; settings.apiPath = 'https://plone.org/api'; expect(toPublicURL('https://plone.org/api/section/content')).toBe( 'https://plone.org/section/content', ); settings.publicURL = savedPublicURL; settings.apiPath = savedApiPath; }); }); describe('isCmsUi', () => { [...settings.nonContentRoutes, '/controlpanel/mypanel'].forEach((route) => { if (typeof route === 'string') { if (settings.nonContentRoutesPublic.includes(route)) { it(`matches non-content-route-public ${route}`, () => { expect(isCmsUi(route)).toBe(false); }); } else { it(`matches non-content-route ${route}`, () => { expect(isCmsUi(`/mycontent/${route}`)).toBe(true); }); } } }); it('returns false on non-cms-ui views', () => { expect(isCmsUi('/mycontent')).toBe(false); }); it('returns true on non content routes', () => { expect(isCmsUi('/mycontent/historyview')).toBe(true); }); it('returns false on public non content routes', () => { expect(isCmsUi('/mycontent/login')).toBe(false); }); }); describe('flattenHTMLToAppURL', () => { it('flattens all occurrences of the api URL from an html snippet', () => { const html = `<a href="${settings.apiPath}/foo/bar">An internal link</a><a href="${settings.apiPath}/foo/baz">second link</a>`; expect(flattenHTMLToAppURL(html)).toBe( '<a href="/foo/bar">An internal link</a><a href="/foo/baz">second link</a>', ); }); it('flattens all occurrences of the api URL from an html snippet, with settings.internalApiPath', () => { const html = `<a href="http://plone:8080/Plone/foo/bar">An internal link</a><a href="http://plone:8080/Plone/foo/baz">second link</a>`; const saved = settings.internalApiPath; settings.internalApiPath = 'http://plone:8080/Plone'; expect(flattenHTMLToAppURL(html)).toBe( '<a href="/foo/bar">An internal link</a><a href="/foo/baz">second link</a>', ); settings.internalApiPath = saved; }); }); describe('isInternalURL', () => { it('tells if an URL from API is internal or not', () => { const href = `${settings.apiPath}/foo/bar`; expect(isInternalURL(href)).toBe(true); }); it('tells if an URL from APP is internal or not', () => { const href = `${settings.publicURL}`; expect(isInternalURL(href)).toBe(true); }); it('tells if an URL from APP is internal or not 2', () => { const href = `${settings.publicURL}/foo/bar`; expect(isInternalURL(href)).toBe(true); }); it('tells if an URL is internal or not, with settings.internalApiPath', () => { const href = `http://plone:8080/Plone/foo/bar`; const saved = settings.internalApiPath; settings.internalApiPath = 'http://plone:8080/Plone'; expect(isInternalURL(href)).toBe(true); settings.internalApiPath = saved; }); it('tells if an URL is external if settings.internalApiPath is empty', () => { const href = `http://google.com`; const saved = settings.internalApiPath; settings.internalApiPath = ''; expect(isInternalURL(href)).toBe(false); settings.internalApiPath = saved; }); it('tells if an URL is internal if it is an anchor', () => { const href = '#anchor'; expect(isInternalURL(href)).toBe(true); }); it('tells if an URL is internal if a root relative path', () => { const href = '/'; expect(isInternalURL(href)).toBe(true); }); it('tells if an URL is internal if a relative path', () => { const href = './../'; expect(isInternalURL(href)).toBe(true); }); it('Behave if URL is not a string', () => { const href = null; expect(isInternalURL(href)).toBe(null); }); it('Behave if URL is not a string II', () => { const href = undefined; expect(isInternalURL(href)).toBe(undefined); }); it('tells if an URL is external if settings.externalroutes is present.', () => { const url = `https://localhost:3000/fb/my-page/contents`; const blacklistedurl = '/blacklisted'; settings.externalRoutes = [ { title: 'My Page', match: '/fb' }, '/blacklisted', ]; settings.publicURL = 'https://localhost:3000'; expect(isInternalURL(url)).toBe(false); expect(isInternalURL(blacklistedurl)).toBe(false); }); }); describe('isUrl', () => { it('isUrl test', () => { const href = `www.example.com`; expect(isUrl(href)).toBe(true); }); it('isUrl test 2', () => { const href = `www.example.com/foo/bar`; expect(isUrl(href)).toBe(true); }); it('isUrl test 3', () => { const href = `https://www.example.com/foo/bar`; expect(isUrl(href)).toBe(true); }); it('isUrl test 4', () => { const href = `https://www`; expect(isUrl(href)).toBe(true); }); it('isUrl test 5', () => { const href = `https://www/foo/bar`; expect(isUrl(href)).toBe(true); }); it('isUrl test 6', () => { // at the end of the day, this is a strange, but valid, URL const href = `www.e`; expect(isUrl(href)).toBe(true); }); it('isUrl test 7', () => { const href = `file://server/folder/file.txt`; expect(isUrl(href)).toBe(true); }); it('isUrl test 8', () => { const href = `file://server.dir.internal/folder/file.txt`; expect(isUrl(href)).toBe(true); }); }); describe('getFieldURL', () => { it('returns app URL if the field is a string', () => { const field = `${settings.apiPath}/foo/bar`; expect(getFieldURL(field)).toBe('/foo/bar'); }); it('returns app URL if the field is an object with "@id"', () => { const field = { '@id': '/foo/bar' }; expect(getFieldURL(field)).toBe('/foo/bar'); }); it('returns app URL if the field is an object with type URL', () => { const field = { '@type': 'URL', value: '/foo/bar' }; expect(getFieldURL(field)).toBe('/foo/bar'); }); it('returns app URL if the field is an object with url or href properties', () => { const fieldUrl = { url: '/foo/bar' }; const fieldHref = { href: '/foo/bar' }; expect(getFieldURL(fieldUrl)).toBe('/foo/bar'); expect(getFieldURL(fieldHref)).toBe('/foo/bar'); }); it('returns array of app URL if the field is an array of strings', () => { const field = [ `${settings.apiPath}/foo/bar/1`, `${settings.apiPath}/foo/bar/2`, ]; expect(getFieldURL(field)).toStrictEqual(['/foo/bar/1', '/foo/bar/2']); }); it('returns array of app URL if the field is an array of objects', () => { const field = [ { '@type': 'URL', value: `${settings.apiPath}/foo/bar/1`, }, { '@type': 'URL', value: `${settings.apiPath}/foo/bar/2`, }, ]; expect(getFieldURL(field)).toStrictEqual(['/foo/bar/1', '/foo/bar/2']); }); }); describe('normalizeUrl', () => { it('normalizeUrl test', () => { const href = `www.example.com`; expect(normalizeUrl(href)).toBe('http://www.example.com'); }); }); describe('removeProtocol', () => { it('removeProtocol test https', () => { const href = `https://www.example.com`; expect(removeProtocol(href)).toBe('www.example.com'); }); it('removeProtocol test http', () => { const href = `http://www.example.com`; expect(removeProtocol(href)).toBe('www.example.com'); }); }); describe('addAppURL', () => { it('addAppURL test https', () => { const href = `/ca/my-page`; expect(addAppURL(href)).toBe('http://localhost:8080/Plone/ca/my-page'); }); }); describe('expandToBackendURL', () => { it('expandToBackendURL test with path', () => { const href = `/ca/my-page`; expect(expandToBackendURL(href)).toBe( 'http://localhost:8080/Plone/++api++/ca/my-page', ); }); it('expandToBackendURL test full URL', () => { const href = `http://localhost:8080/Plone/ca/my-page`; expect(expandToBackendURL(href)).toBe( 'http://localhost:8080/Plone/++api++/ca/my-page', ); }); it('expandToBackendURL test full URL - legacyTraverse true', () => { settings.apiPath = 'https://plone.org/api'; settings.legacyTraverse = true; const href = `https://plone.org/api/ca/my-page`; expect(expandToBackendURL(href)).toBe('https://plone.org/api/ca/my-page'); }); it('expandToBackendURL test full URL - deployed seamless', () => { settings.apiPath = 'https://plone.org'; const href = `https://plone.org/ca/my-page`; expect(expandToBackendURL(href)).toBe( 'https://plone.org/++api++/ca/my-page', ); }); }); describe('flattenScales', () => { it('flattenScales image is not set', () => { const id = '/halfdome2022-2.jpg'; const image = undefined; expect(flattenScales(id, image)).toBe(undefined); }); it('flattenScales test from the catalog', () => { const id = '/halfdome2022-2.jpg'; const image = { 'content-type': 'image/jpeg', download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg', filename: 'halfdome2022.jpg', height: 665, scales: { great: { download: '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg', height: 665, width: 1182, }, huge: { download: '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg', height: 665, width: 1182, }, }, size: 319364, width: 1182, }; expect(flattenScales(id, image)).toStrictEqual({ 'content-type': 'image/jpeg', download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg', filename: 'halfdome2022.jpg', height: 665, scales: { great: { download: '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg', height: 665, width: 1182, }, huge: { download: '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg', height: 665, width: 1182, }, }, size: 319364, width: 1182, }); }); it('[preview_image_link] flattenScales test from the catalog', () => { const id = '/halfdome2022-2.jpg'; const image = { base_path: '/broccoli.jpg', 'content-type': 'image/jpeg', download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg', filename: 'halfdome2022.jpg', height: 665, scales: { great: { download: '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg', height: 665, width: 1182, }, huge: { download: '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg', height: 665, width: 1182, }, }, size: 319364, width: 1182, }; expect(flattenScales(id, image)).toStrictEqual({ base_path: '/broccoli.jpg', 'content-type': 'image/jpeg', download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg', filename: 'halfdome2022.jpg', height: 665, scales: { great: { download: '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg', height: 665, width: 1182, }, huge: { download: '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg', height: 665, width: 1182, }, }, size: 319364, width: 1182, }); }); it('flattenScales test from serialization', () => { const id = 'http://localhost:3000/halfdome2022-2.jpg'; const image = { 'content-type': 'image/jpeg', download: 'http://localhost:3000/halfdome2022-2.jpg/@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg', filename: 'halfdome2022.jpg', height: 665, scales: { great: { download: 'http://localhost:3000/halfdome2022-2.jpg/@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg', height: 665, width: 1182, }, huge: { download: 'http://localhost:3000/halfdome2022-2.jpg/@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg', height: 665, width: 1182, }, }, size: 319364, width: 1182, }; expect(flattenScales(id, image)).toStrictEqual({ 'content-type': 'image/jpeg', download: '@@images/image-1182-cf763ae23c52340d8a17a7afdb26c8cb.jpeg', filename: 'halfdome2022.jpg', height: 665, scales: { great: { download: '@@images/image-1200-539ab119ebadc7d011798980a4a5e8d4.jpeg', height: 665, width: 1182, }, huge: { download: '@@images/image-1600-188968febc677890c1b99d5339f9bef1.jpeg', height: 665, width: 1182, }, }, size: 319364, width: 1182, }); }); }); });