Skip to content

Commit

Permalink
fix(UVE): RunnableLink construction for page tool analytics #29206 (#…
Browse files Browse the repository at this point in the history
…29649)

### Proposed Changes
* Update URL construction logic to remove protocol and port for Mozilla
tool.
* Adjust URL construction for Wave and Security Headers tools using
`URL().origin` .

### Additional Info
This change aligns the URL formats with the requirements of the
analytics tools, ensuring compatibility and preventing potential errors
due to unsupported URL components.

This PR fixes #29206

## Differences
### Mozilla Observatory (Before and After)

![image](https://github.com/user-attachments/assets/c8d87266-ac4d-47d9-99c2-3e1bd5afb179)
  • Loading branch information
valentinogiardino authored Aug 20, 2024
1 parent 13e51d4 commit 127480c
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 20 deletions.
2 changes: 1 addition & 1 deletion core-web/apps/dotcms-ui/src/assets/seo/page-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"title": "Mozilla Observatory",
"description": "The Mozilla Observatory has helped hundreds of thousands of websites by teaching developers, system administrators, and security professionals how to configure their sites safely and securely. ",
"tags": ["Security", "Best Practices"],
"runnableLink": "https://developer.mozilla.org/en-US/observatory/analyze?host={requestHostName}"
"runnableLink": "https://developer.mozilla.org/en-US/observatory/analyze?host={domainName}"
},
{
"icon": "assets/seo/security-headers.png",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('DotPageToolsSeoComponent', () => {
beforeEach(() => {
pageToolUrlParamsTest = {
currentUrl: '/blogTest',
requestHostName: 'localhost',
requestHostName: 'http://localhost',
siteId: '123',
languageId: 1
};
Expand Down
6 changes: 3 additions & 3 deletions core-web/libs/utils-testing/src/lib/dot-page-tools.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ export const mockPageTools: DotPageTools = {
'The WAVE® evaluation suite helps educate authors on how to make their web content more accessible to individuals with disabilities. WAVE can identify many accessibility and Web Content Accessibility Guideline (WCAG) errors, but also facilitates human evaluation of web content.',
tags: ['Accessibility', 'WCAG'],
runnableLink:
'https://wave.webaim.org/report#/localhost/blogTest?host_id=123?language_id=1'
'https://wave.webaim.org/report#/http://localhost/blogTest?host_id=123?language_id=1'
},
{
icon: 'assets/seo/mozilla.png',
title: 'Mozilla Observatory',
description:
'The Mozilla Observatory has helped hundreds of thousands of websites by teaching developers, system administrators, and security professionals how to configure their sites safely and securely. ',
tags: ['Security', 'Best Practices'],
runnableLink: 'https://observatory.mozilla.org/analyze/localhost'
runnableLink: 'https://developer.mozilla.org/en-US/observatory/analyze?host=localhost'
},
{
icon: 'assets/seo/security-headers.png',
Expand All @@ -26,7 +26,7 @@ export const mockPageTools: DotPageTools = {
'This tool is designed to help you better deploy and understand modern security features that are available for your website. It will provide a simple to understand grading system for how well your site follows best practices, as well as suggestions for how to make improvement.',
tags: ['Securty', 'Best Practices'],
runnableLink:
'https://securityheaders.com/?q=localhost/blogTest&host_id=123&language_id=1&followRedirects=on'
'https://securityheaders.com/?q=http://localhost/blogTest&host_id=123&language_id=1&followRedirects=on'
}
]
};
99 changes: 85 additions & 14 deletions core-web/libs/utils/src/lib/dot-utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ describe('Dot Utils', () => {
'https://wave.webaim.org/report#/{requestHostName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '',
requestHostName: 'my-site',
requestHostName: 'https://my-site.com',
siteId: '',
languageId: 1
};

expect(getRunnableLink(url, params)).toEqual(
'https://wave.webaim.org/report#/my-site?language_id=1'
'https://wave.webaim.org/report#/https://my-site.com?language_id=1'
);
});

Expand All @@ -145,28 +145,27 @@ describe('Dot Utils', () => {
'https://wave.webaim.org/report#/{requestHostName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'my-site',
requestHostName: 'https://my-site.com',
siteId: '50a79decd9e21702cb2f52fc4935a52b',
languageId: 1
};

expect(getRunnableLink(url, params)).toEqual(
'https://wave.webaim.org/report#/my-site/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1'
'https://wave.webaim.org/report#/https://my-site.com/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1'
);
});

it('should replace {requestHostName} and append query parameters in Mozilla Observatory URL', () => {
const url =
'https://developer.mozilla.org/en-US/observatory/analyze?host={requestHostName}';
const url = 'https://developer.mozilla.org/en-US/observatory/analyze?host={domainName}';
const params: DotPageToolUrlParams = {
currentUrl: '',
requestHostName: 'my-site',
requestHostName: 'http://my-site.com:80',
siteId: '50a79decd9e21702cb2f52fc4935a52b',
languageId: 1
};

expect(getRunnableLink(url, params)).toEqual(
'https://developer.mozilla.org/en-US/observatory/analyze?host=my-site'
'https://developer.mozilla.org/en-US/observatory/analyze?host=my-site.com'
);
});

Expand All @@ -175,13 +174,13 @@ describe('Dot Utils', () => {
'https://securityheaders.com/?q={requestHostName}{currentUrl}{urlSearchParams}&followRedirects=on';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'my-site',
requestHostName: 'https://my-site.com',
siteId: '50a79decd9e21702cb2f52fc4935a52b',
languageId: 1
};

expect(getRunnableLink(url, params)).toEqual(
'https://securityheaders.com/?q=my-site/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1&followRedirects=on'
'https://securityheaders.com/?q=https://my-site.com/current-page?host_id=50a79decd9e21702cb2f52fc4935a52b&language_id=1&followRedirects=on'
);
});

Expand All @@ -200,12 +199,14 @@ describe('Dot Utils', () => {
const url = 'https://example.com/{requestHostName}/page';
const params: DotPageToolUrlParams = {
currentUrl: '',
requestHostName: 'my-site',
requestHostName: 'https://my-site.com',
siteId: '',
languageId: 1
};

expect(getRunnableLink(url, params)).toEqual('https://example.com/my-site/page');
expect(getRunnableLink(url, params)).toEqual(
'https://example.com/https://my-site.com/page'
);
});

it('should replace {currentUrl} with the actual currentUrl', () => {
Expand Down Expand Up @@ -238,13 +239,13 @@ describe('Dot Utils', () => {
const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'my-site',
requestHostName: 'https://my-site.com',
siteId: '123',
languageId: 456
};

expect(getRunnableLink(url, params)).toEqual(
'https://example.com/my-site/current-page?host_id=123&language_id=456'
'https://example.com/https://my-site.com/current-page?host_id=123&language_id=456'
);
});

Expand Down Expand Up @@ -295,5 +296,75 @@ describe('Dot Utils', () => {

expect(getRunnableLink(url, params)).toEqual('https://example.com/');
});

it('should and respect https protocol and port in requestHostName', () => {
const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'https://my-site.com:4200',
siteId: '123',
languageId: 456
};

expect(getRunnableLink(url, params)).toEqual(
'https://example.com/https://my-site.com:4200/current-page?host_id=123&language_id=456'
);
});

it('should and respect http protocol and port in requestHostName', () => {
const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'http://my-site.com:4200',
siteId: '123',
languageId: 456
};

expect(getRunnableLink(url, params)).toEqual(
'https://example.com/http://my-site.com:4200/current-page?host_id=123&language_id=456'
);
});

it('should remove port and protocol in domainName', () => {
const url = 'https://example.com/{domainName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'https://my-site.com:4200',
siteId: '123',
languageId: 456
};

expect(getRunnableLink(url, params)).toEqual(
'https://example.com/my-site.com/current-page?host_id=123&language_id=456'
);
});

it('should remove port in requestHostName given https protocol and 443 port ', () => {
const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'https://my-site.com:443',
siteId: '123',
languageId: 456
};

expect(getRunnableLink(url, params)).toEqual(
'https://example.com/https://my-site.com/current-page?host_id=123&language_id=456'
);
});

it('should remove port in requestHostName given http protocol and 80 port ', () => {
const url = 'https://example.com/{requestHostName}{currentUrl}{urlSearchParams}';
const params: DotPageToolUrlParams = {
currentUrl: '/current-page',
requestHostName: 'http://my-site.com:80',
siteId: '123',
languageId: 456
};

expect(getRunnableLink(url, params)).toEqual(
'https://example.com/http://my-site.com/current-page?host_id=123&language_id=456'
);
});
});
});
4 changes: 3 additions & 1 deletion core-web/libs/utils/src/lib/dot-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,10 @@ export function getRunnableLink(url: string, currentPageUrlParams: DotPageToolUr
if (languageId) pageParams.append('language_id', String(languageId));

// Replace placeholders in the base URL with actual values and append query parameters if they exist
const requestHostUrl = requestHostName ? new URL(requestHostName) : null;
const finalUrl = url
.replace(/{requestHostName}/g, requestHostName ?? '')
.replace(/{requestHostName}/g, requestHostUrl ? requestHostUrl.origin : '')
.replace(/{domainName}/g, requestHostUrl ? requestHostUrl.hostname : '')
.replace(/{currentUrl}/g, currentUrl ?? '')
.replace(/{urlSearchParams}/g, pageParams.toString() ? `?${pageParams.toString()}` : '');

Expand Down

0 comments on commit 127480c

Please sign in to comment.