test
diff --git a/__tests__/shared/utils/url.test.js b/__tests__/shared/utils/url.test.js
new file mode 100644
index 000000000..47eebe8aa
--- /dev/null
+++ b/__tests__/shared/utils/url.test.js
@@ -0,0 +1,40 @@
+import {
+ getMemberProfileUrl,
+ getMenuWithDirectProfileLink,
+ updateLegacyProfileLinks,
+} from 'utils/url';
+
+describe('member profile URLs', () => {
+ it('uses the configured profile application URL', () => {
+ expect(getMemberProfileUrl('tourist'))
+ .toBe('https://profiles.topcoder-dev.com/tourist');
+ });
+
+ it('normalizes the profile entry in a navigation menu', () => {
+ const menu = [{
+ id: 'community',
+ secondaryMenu: [{ id: 'myprofile', href: '/members/placeholder' }],
+ }];
+
+ expect(getMenuWithDirectProfileLink(menu, 'tourist')[0].secondaryMenu[0])
+ .toEqual({
+ id: 'profile',
+ href: 'https://profiles.topcoder-dev.com/tourist',
+ });
+ });
+
+ it('updates only an exact legacy profile anchor rendered by navigation', () => {
+ const root = document.createElement('nav');
+ root.innerHTML = [
+ 'Profile',
+ '
Badges',
+ ].join('');
+
+ updateLegacyProfileLinks(root, 'tourist');
+
+ expect(root.querySelector('a').getAttribute('href'))
+ .toBe('https://profiles.topcoder-dev.com/tourist');
+ expect(root.querySelectorAll('a')[1].getAttribute('href'))
+ .toBe('/members/tourist/badges');
+ });
+});
diff --git a/automated-smoke-test/config/automation-config-dev.json b/automated-smoke-test/config/automation-config-dev.json
index 9ac9bf711..d249ce956 100644
--- a/automated-smoke-test/config/automation-config-dev.json
+++ b/automated-smoke-test/config/automation-config-dev.json
@@ -34,7 +34,7 @@
},
"subMenuUrlsAfterLogin": {
"dashboard": "https://community-app.topcoder-dev.com/my-dashboard",
- "myProfile": "https://community-app.topcoder-dev.com/members/tester1234",
+ "myProfile": "https://profiles.topcoder-dev.com/tester1234",
"payments": "https://community.topcoder-dev.com/PactsMemberServlet?module=PaymentHistory&full_list=false",
"competitiveProgramming": "https://community-app.topcoder-dev.com/community/arena",
"forums": "https://apps.topcoder-dev.com/forums/"
diff --git a/automated-smoke-test/config/automation-config-local.json b/automated-smoke-test/config/automation-config-local.json
index c2ca342f5..925be12c4 100644
--- a/automated-smoke-test/config/automation-config-local.json
+++ b/automated-smoke-test/config/automation-config-local.json
@@ -34,7 +34,7 @@
},
"subMenuUrlsAfterLogin": {
"dashboard": "http://localhost:3000/my-dashboard",
- "myProfile": "http://localhost:3000/members/CustomerUser",
+ "myProfile": "https://profiles.topcoder-dev.com/CustomerUser",
"payments": "https://community.topcoder.com/PactsMemberServlet?module=PaymentHistory&full_list=false",
"forums": "https://apps.topcoder.com/forums/"
},
diff --git a/automated-smoke-test/config/automation-config-prod.json b/automated-smoke-test/config/automation-config-prod.json
index d05c56008..f31b77b8e 100644
--- a/automated-smoke-test/config/automation-config-prod.json
+++ b/automated-smoke-test/config/automation-config-prod.json
@@ -34,7 +34,7 @@
},
"subMenuUrlsAfterLogin": {
"dashboard": "https://www.topcoder.com/my-dashboard",
- "myProfile": "https://www.topcoder.com/members/CustomerUser",
+ "myProfile": "https://profiles.topcoder.com/CustomerUser",
"payments": "https://community.topcoder.com/PactsMemberServlet?module=PaymentHistory&full_list=false",
"forums": "https://apps.topcoder.com/forums/"
},
diff --git a/automated-smoke-test/page-objects/pages/topcoder/header/header.po.ts b/automated-smoke-test/page-objects/pages/topcoder/header/header.po.ts
index 45e41a47e..7c3ac18e7 100644
--- a/automated-smoke-test/page-objects/pages/topcoder/header/header.po.ts
+++ b/automated-smoke-test/page-objects/pages/topcoder/header/header.po.ts
@@ -134,7 +134,7 @@ export class HeaderPage {
* Gets the notification bell icon
*/
private async getBellIcon() {
- const xpath = `//a[contains(@href, '/members/${ConfigHelper.getUserName()}')]/parent::div/parent::div/div[position()=1]`;
+ const xpath = `//a[contains(@href, 'profiles.topcoder') and contains(@href, '/${ConfigHelper.getUserName()}')]/parent::div/parent::div/div[position()=1]`;
const els = await ElementHelper.getAllElementsByXPath(xpath);
return els[1];
}
diff --git a/config/backup-default.js b/config/backup-default.js
index 2b0d74756..0d1ce386e 100644
--- a/config/backup-default.js
+++ b/config/backup-default.js
@@ -310,9 +310,9 @@ module.exports = {
logged: true,
},
{
- id: 'myprofile',
+ id: 'profile',
title: 'My Profile',
- href: '/members/willFilledByUserName',
+ href: 'https://profiles.topcoder-dev.com/willFilledByUserName',
logged: true,
},
{
diff --git a/config/default.js b/config/default.js
index ec826e361..91b955c89 100644
--- a/config/default.js
+++ b/config/default.js
@@ -314,9 +314,9 @@ module.exports = {
logged: true,
},
{
- id: 'myprofile',
+ id: 'profile',
title: 'My Profile',
- href: '/members/willFilledByUserName',
+ href: 'https://profiles.topcoder-dev.com/willFilledByUserName',
logged: true,
},
{
diff --git a/config/production.js b/config/production.js
index f805153f7..17a98d876 100644
--- a/config/production.js
+++ b/config/production.js
@@ -100,9 +100,9 @@ module.exports = {
logged: true,
},
{
- id: 'myprofile',
+ id: 'profile',
title: 'My Profile',
- href: '/members/willFilledByUserName?ref=nav',
+ href: 'https://profiles.topcoder.com/willFilledByUserName',
logged: true,
},
{
diff --git a/src/shared/actions/recruitCRM.js b/src/shared/actions/recruitCRM.js
index 1597b45fa..ba1d83d67 100644
--- a/src/shared/actions/recruitCRM.js
+++ b/src/shared/actions/recruitCRM.js
@@ -2,6 +2,7 @@ import { redux } from 'topcoder-react-utils';
import Service from 'services/recruitCRM';
import _ from 'lodash';
import { getCustomField } from 'utils/gigs';
+import { getMemberProfileUrl } from 'utils/url';
/**
* Jobs page fetch init
@@ -86,7 +87,7 @@ function normalizeRecruitPayload(job, payload) {
custom_fields: [
{
field_id: 1,
- value: payload.tcProfileLink || (payload.handle ? `https://topcoder.com/members/${payload.handle}` : ''),
+ value: payload.tcProfileLink || (payload.handle ? getMemberProfileUrl(payload.handle) : ''),
},
{
field_id: 2,
diff --git a/src/shared/components/Content/index.jsx b/src/shared/components/Content/index.jsx
index a2e2d4681..415606fa9 100644
--- a/src/shared/components/Content/index.jsx
+++ b/src/shared/components/Content/index.jsx
@@ -7,6 +7,7 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { isomorphy } from 'topcoder-react-utils';
+import { getMemberProfileUrl } from 'utils/url';
import './style.scss';
@@ -247,13 +248,13 @@ export default function Content() {
endpoint.
Valid links on dev:
-
+
Profile 1.
-
+
-
+
Profile 2.
-
+
Stand-alone terms of use page:
diff --git a/src/shared/components/GSheet/index.jsx b/src/shared/components/GSheet/index.jsx
index c09a00fa4..545f9de7e 100644
--- a/src/shared/components/GSheet/index.jsx
+++ b/src/shared/components/GSheet/index.jsx
@@ -9,6 +9,7 @@ import _ from 'lodash';
import React, { Component } from 'react';
import { Scrollbars } from 'react-custom-scrollbars';
import cn from 'classnames';
+import { getMemberProfileUrl } from 'utils/url';
import './style.scss';
export default class GSheet extends Component {
@@ -88,7 +89,7 @@ export default class GSheet extends Component {
{
(config.pick || sheet.rows[0]._sheet.headerValues).map(c => (
- {c.toLowerCase() === 'handle' ? ({record[c]}) : record[c]}
+ {c.toLowerCase() === 'handle' ? ({record[c]}) : record[c]}
|
))
}
diff --git a/src/shared/components/Gigs/GigApply/index.jsx b/src/shared/components/Gigs/GigApply/index.jsx
index f3ea35051..55db5d652 100644
--- a/src/shared/components/Gigs/GigApply/index.jsx
+++ b/src/shared/components/Gigs/GigApply/index.jsx
@@ -12,6 +12,7 @@ import DropdownSkills from 'components/GUIKit/DropdownSkills';
import RadioButton from 'components/GUIKit/RadioButton';
import Checkbox from 'components/GUIKit/Checkbox';
import { getCustomField } from 'utils/gigs';
+import { getMemberProfileUrl } from 'utils/url';
import Modal from 'components/Contentful/Modal';
import FilestackFilePicker from 'components/GUIKit/FilePicker';
import Dropdown from 'components/GUIKit/Dropdown';
@@ -238,11 +239,11 @@ export default function GigApply(props) {
readonly
/>
onFormInputChange('tcProfileLink', val)}
errorMsg={formErrors.tcProfileLink}
- value={formData.handle ? `https://topcoder.com/members/${formData.handle}` : null}
+ value={formData.handle ? getMemberProfileUrl(formData.handle) : null}
readonly
/>
diff --git a/src/shared/components/HallOfFamePage/Champions/Track/index.jsx b/src/shared/components/HallOfFamePage/Champions/Track/index.jsx
index d73836c18..3da691d2c 100644
--- a/src/shared/components/HallOfFamePage/Champions/Track/index.jsx
+++ b/src/shared/components/HallOfFamePage/Champions/Track/index.jsx
@@ -5,6 +5,7 @@ import React from 'react';
import PT from 'prop-types';
import _ from 'lodash';
import { themr } from 'react-css-super-themr';
+import { getMemberProfileUrl } from 'utils/url';
import defaultStyles from './styles.scss';
@@ -22,7 +23,7 @@ const Track = ({
data.fields.members.map(member => (