[CLD-9285] Add server version and edition (team vs ent) to ExternalLink component (#31783)

* Add server version and edition (team vs ent) to ExternalLink component

* fix: add proper Redux state setup to datetime_input.test.tsx

The test was failing because the useExternalLink hook (added in this PR)
requires access to config and license Redux state, but the datetime_input
tests weren't providing proper initial state. This caused components to
receive undefined values from Redux selectors, potentially affecting
locale/date formatting behavior.

Added defaultState with proper config and license structure to match
what other tests in the codebase use, ensuring consistent test environment.

Co-authored-by: Nick Misasi <nickmisasi@users.noreply.github.com>

* Revert to master

* Revert to master

---------

Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: Nick Misasi <nickmisasi@users.noreply.github.com>
Этот коммит содержится в:
Nick Misasi
2025-06-24 11:11:19 -04:00
коммит произвёл GitHub
родитель 1148bea55b
Коммит 5d7c3b52ed
11 изменённых файлов: 53 добавлений и 29 удалений

Просмотреть файл

@@ -78,7 +78,7 @@ describe('components/AboutBuildModal', () => {
expect(screen.getByTestId('aboutModalBuildNumber')).toHaveTextContent('Build Number: 123456');
expect(screen.getByText('Mattermost Enterprise Edition')).toBeInTheDocument();
expect(screen.getByText('Modern communication from behind your firewall.')).toBeInTheDocument();
expect(screen.getByRole('link', {name: 'mattermost.com'})).toHaveAttribute('href', 'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
expect(screen.getByRole('link', {name: 'mattermost.com'})).toHaveAttribute('href', 'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=&edition=enterprise&server_version=3.6.0');
expect(screen.getByText('EE Build Hash: 0123456789abcdef', {exact: false})).toBeInTheDocument();
expect(screen.queryByText('Hostname: mock.localhost', {exact: false})).toBeInTheDocument();
@@ -100,7 +100,7 @@ describe('components/AboutBuildModal', () => {
expect(screen.getByTestId('aboutModalBuildNumber')).toHaveTextContent('Build Number: 123456');
expect(screen.getByText('Mattermost Team Edition')).toBeInTheDocument();
expect(screen.getByText('All your team communication in one place, instantly searchable and accessible anywhere.')).toBeInTheDocument();
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=&edition=team&server_version=3.6.0');
expect(screen.queryByText('EE Build Hash: 0123456789abcdef')).not.toBeInTheDocument();
expect(screen.queryByText('Hostname: disconnected', {exact: false})).toBeInTheDocument();
@@ -150,7 +150,7 @@ describe('components/AboutBuildModal', () => {
expect(screen.getByTestId('aboutModalBuildNumber')).toHaveTextContent('Build Number: n/a');
expect(screen.getByText('Mattermost Team Edition')).toBeInTheDocument();
expect(screen.getByText('All your team communication in one place, instantly searchable and accessible anywhere.')).toBeInTheDocument();
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=');
expect(screen.getByRole('link', {name: 'mattermost.com/community/'})).toHaveAttribute('href', 'https://mattermost.com/community/?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=&sid=&edition=team&server_version=dev');
expect(screen.queryByText('EE Build Hash: 0123456789abcdef')).not.toBeInTheDocument();
expect(screen.queryByText('Hostname: server did not provide hostname', {exact: false})).toBeInTheDocument();
@@ -193,7 +193,7 @@ describe('components/AboutBuildModal', () => {
const state = {
entities: {
general: {
config: {},
config,
license: {
Cloud: 'false',
},
@@ -213,9 +213,9 @@ describe('components/AboutBuildModal', () => {
state,
);
expect(screen.getByRole('link', {name: 'Terms of Use'})).toHaveAttribute('href', `${AboutLinks.TERMS_OF_SERVICE}?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=currentUserId&sid=`);
expect(screen.getByRole('link', {name: 'Terms of Use'})).toHaveAttribute('href', `${AboutLinks.TERMS_OF_SERVICE}?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=currentUserId&sid=&edition=enterprise&server_version=3.6.0`);
expect(screen.getByRole('link', {name: 'Privacy Policy'})).toHaveAttribute('href', `${AboutLinks.PRIVACY_POLICY}?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=currentUserId&sid=`);
expect(screen.getByRole('link', {name: 'Privacy Policy'})).toHaveAttribute('href', `${AboutLinks.PRIVACY_POLICY}?utm_source=mattermost&utm_medium=in-product&utm_content=about_build_modal&uid=currentUserId&sid=&edition=enterprise&server_version=3.6.0`);
expect(screen.getByRole('link', {name: 'Terms of Use'})).not.toHaveAttribute('href', config?.TermsOfServiceLink);
expect(screen.getByRole('link', {name: 'Privacy Policy'})).not.toHaveAttribute('href', config?.PrivacyPolicyLink);
@@ -282,6 +282,19 @@ describe('components/AboutBuildModal', () => {
...props,
};
return renderWithContext(<AboutBuildModal {...allProps}/>);
// Create state with the config and license for useExternalLink hook to access
const state = {
entities: {
general: {
config: allProps.config,
license: allProps.license,
},
users: {
currentUserId: '',
},
},
};
return renderWithContext(<AboutBuildModal {...allProps}/>, state);
}
});

Просмотреть файл

@@ -131,7 +131,7 @@ describe('components/admin_console/billing/billing_history', () => {
expect(screen.queryByTestId(invoiceA.id)).not.toBeInTheDocument();
expect(screen.queryByTestId(invoiceB.id)).not.toBeInTheDocument();
expect(screen.getByRole('link')).toHaveAttribute('href', CloudLinks.BILLING_DOCS + '?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=billing_history&uid=current_user_id&sid=');
expect(screen.getByRole('link')).toHaveAttribute('href', CloudLinks.BILLING_DOCS + '?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=billing_history&uid=current_user_id&sid=&edition=team&server_version=');
expect(screen.getByRole('link')).toHaveTextContent('See how billing works');
expect(screen.getByTestId('no-invoices')).toHaveTextContent(NO_INVOICES_LEGEND);
});

Просмотреть файл

@@ -65,10 +65,10 @@ describe('components/feature_discovery', () => {
const featureLink = screen.getByTestId('featureDiscovery_secondaryCallToAction');
expect(featureLink).toBeInTheDocument();
expect(featureLink).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(featureLink).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=&edition=team&server_version=');
expect(featureLink).toHaveTextContent('Learn more');
expect(screen.getByText('Mattermost Software and Services License Agreement')).toHaveAttribute('href', 'https://mattermost.com/pl/software-and-services-license-agreement?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(screen.getByText('Privacy Policy')).toHaveAttribute('href', AboutLinks.PRIVACY_POLICY + '?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(screen.getByText('Mattermost Software and Services License Agreement')).toHaveAttribute('href', 'https://mattermost.com/pl/software-and-services-license-agreement?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=&edition=team&server_version=');
expect(screen.getByText('Privacy Policy')).toHaveAttribute('href', AboutLinks.PRIVACY_POLICY + '?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=&edition=team&server_version=');
expect(getPrevTrialLicense).toHaveBeenCalled();
expect(getCloudSubscription).not.toHaveBeenCalled();
@@ -121,12 +121,12 @@ describe('components/feature_discovery', () => {
//this option is visible only when it is cloud environment
expect(screen.getByRole('button', {name: 'Contact sales'})).toBeInTheDocument();
expect(screen.getByTestId('featureDiscovery_secondaryCallToAction')).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(screen.getByTestId('featureDiscovery_secondaryCallToAction')).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=&edition=team&server_version=');
const featureLink = screen.getByTestId('featureDiscovery_secondaryCallToAction');
expect(featureLink).toBeInTheDocument();
expect(featureLink).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=');
expect(featureLink).toHaveAttribute('href', 'https://test.mattermost.com/secondary/?utm_source=mattermost&utm_medium=in-product&utm_content=feature_discovery&uid=&sid=&edition=team&server_version=');
expect(featureLink).toHaveTextContent('Learn more');
expect(getPrevTrialLicense).toHaveBeenCalled();

Просмотреть файл

@@ -19,6 +19,8 @@ export type ExternalLinkQueryParams = {
export function useExternalLink(href: string, location: string = '', overwriteQueryParams: ExternalLinkQueryParams = {}): [string, Record<string, string>] {
const userId = useSelector(getCurrentUserId);
const config = useSelector(getConfig);
const license = useSelector(getLicense);
const telemetryId = useSelector((state: GlobalState) => getConfig(state)?.TelemetryId || '');
const isCloud = useSelector((state: GlobalState) => getLicense(state)?.Cloud === 'true');
@@ -29,6 +31,13 @@ export function useExternalLink(href: string, location: string = '', overwriteQu
const parsedUrl = new URL(href);
// Determine edition type (enterprise vs team)
const isEnterpriseReady = config?.BuildEnterpriseReady === 'true';
const edition = isEnterpriseReady ? 'enterprise' : 'team';
// Determine server version
const serverVersion = config?.BuildNumber === 'dev' ? config.BuildNumber : (config?.Version || '');
const existingURLSearchParams = parsedUrl.searchParams;
const existingQueryParamsObj = Object.fromEntries(existingURLSearchParams.entries());
const queryParams = {
@@ -37,11 +46,13 @@ export function useExternalLink(href: string, location: string = '', overwriteQu
utm_content: location,
uid: userId,
sid: telemetryId,
edition,
server_version: serverVersion,
...overwriteQueryParams,
...existingQueryParamsObj,
};
parsedUrl.search = Object.entries(queryParams).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join('&');
return [parsedUrl.toString(), queryParams];
}, [href, isCloud, location, overwriteQueryParams, telemetryId, userId]);
}, [href, isCloud, location, overwriteQueryParams, telemetryId, userId, config, license]);
}

Просмотреть файл

@@ -18,7 +18,7 @@ exports[`components/external_link should match snapshot 1`] = `
location="test"
>
<a
href="https://mattermost.com/?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=test&uid=currentUserId&sid="
href="https://mattermost.com/?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=test&uid=currentUserId&sid=&edition=team&server_version="
location="test"
onClick={[Function]}
rel="noopener noreferrer"

Просмотреть файл

@@ -98,7 +98,7 @@ describe('components/external_link', () => {
expect(screen.queryByText('Click Me')).toHaveAttribute(
'href',
'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=test&uid=currentUserId&sid=&test=true',
'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=test&uid=currentUserId&sid=&edition=team&server_version=&test=true',
);
});
@@ -191,7 +191,7 @@ describe('components/external_link', () => {
expect(screen.queryByText('Click Me')).toHaveAttribute(
'href',
'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=test&uid=currentUserId&sid=#desktop',
'https://mattermost.com/?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=test&uid=currentUserId&sid=&edition=team&server_version=#desktop',
);
});
});

Просмотреть файл

@@ -194,7 +194,7 @@ exports[`components/integrations/InstalledOutgoingOAuthConnections should match
location="installed_outgoing_oauth_connections"
>
<a
href="https://mattermost.com/pl/setup-oauth-2.0?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=installed_outgoing_oauth_connections&uid=current_user_id&sid="
href="https://mattermost.com/pl/setup-oauth-2.0?utm_source=mattermost&utm_medium=in-product-cloud&utm_content=installed_outgoing_oauth_connections&uid=current_user_id&sid=&edition=team&server_version="
location="installed_outgoing_oauth_connections"
onClick={[Function]}
rel="noopener noreferrer"

Просмотреть файл

@@ -231,7 +231,7 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
expect(screen.getByRole('link')).toHaveAttribute(
'href',
LicenseLinks.CONTACT_SALES +
'?utm_source=mattermost&utm_medium=in-product&utm_content=overage_users_banner&uid=current_user&sid=',
'?utm_source=mattermost&utm_medium=in-product&utm_content=overage_users_banner&uid=current_user&sid=&edition=team&server_version=',
);
expect(trackEvent).toBeCalledTimes(2);
expect(trackEvent).toBeCalledWith('insights', 'click_true_up_error', {
@@ -337,7 +337,7 @@ describe('components/invitation_modal/overage_users_banner_notice', () => {
expect(screen.getByRole('link')).toHaveAttribute(
'href',
LicenseLinks.CONTACT_SALES +
'?utm_source=mattermost&utm_medium=in-product&utm_content=overage_users_banner&uid=current_user&sid=',
'?utm_source=mattermost&utm_medium=in-product&utm_content=overage_users_banner&uid=current_user&sid=&edition=team&server_version=',
);
expect(trackEvent).toBeCalledTimes(2);
expect(trackEvent).toBeCalledWith('insights', 'click_true_up_error', {

Просмотреть файл

@@ -334,7 +334,7 @@ Object {
>
By selecting Start trial, I agree to the
<a
href="https://mattermost.com/software-evaluation-agreement/?utm_source=mattermost&utm_medium=in-product&utm_content=start_trial_form_modal&uid=user1&sid=test123"
href="https://mattermost.com/software-evaluation-agreement/?utm_source=mattermost&utm_medium=in-product&utm_content=start_trial_form_modal&uid=user1&sid=test123&edition=team&server_version="
location="start_trial_form_modal"
rel="noopener noreferrer"
target="_blank"
@@ -343,7 +343,7 @@ Object {
</a>
,
<a
href="https://mattermost.com/pl/privacy-policy/?utm_source=mattermost&utm_medium=in-product&utm_content=start_trial_form_modal&uid=user1&sid=test123"
href="https://mattermost.com/pl/privacy-policy/?utm_source=mattermost&utm_medium=in-product&utm_content=start_trial_form_modal&uid=user1&sid=test123&edition=team&server_version="
location="start_trial_form_modal"
rel="noopener noreferrer"
target="_blank"

Просмотреть файл

@@ -23,7 +23,7 @@ describe('components/TeamSettings/OpenInvite', () => {
expect(title).toBeInTheDocument();
const externalLink = screen.getByText('Learn More');
expect(externalLink).toBeInTheDocument();
expect(externalLink).toHaveAttribute('href', 'https://mattermost.com/pl/default-ldap-group-constrained-team-channel.html?utm_source=mattermost&utm_medium=in-product&utm_content=open_invite&uid=&sid=');
expect(externalLink).toHaveAttribute('href', 'https://mattermost.com/pl/default-ldap-group-constrained-team-channel.html?utm_source=mattermost&utm_medium=in-product&utm_content=open_invite&uid=&sid=&edition=team&server_version=');
});
test('should render the checkbox when the team is not constrained and not checked', () => {

Просмотреть файл

@@ -56,7 +56,7 @@ Object {
>
<a
class="btn btn-link"
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid="
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid=&edition=team&server_version="
location="user_settings_notifications"
rel="noopener noreferrer"
target="_blank"
@@ -367,7 +367,7 @@ Object {
>
<a
class="btn btn-link"
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid="
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid=&edition=team&server_version="
location="user_settings_notifications"
rel="noopener noreferrer"
target="_blank"
@@ -737,7 +737,7 @@ Object {
>
<a
class="btn btn-link"
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid="
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid=&edition=team&server_version="
location="user_settings_notifications"
rel="noopener noreferrer"
target="_blank"
@@ -1050,7 +1050,7 @@ Object {
>
<a
class="btn btn-link"
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid="
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid=&edition=team&server_version="
location="user_settings_notifications"
rel="noopener noreferrer"
target="_blank"
@@ -1422,7 +1422,7 @@ Object {
>
<a
class="btn btn-link"
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid="
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid=&edition=team&server_version="
location="user_settings_notifications"
rel="noopener noreferrer"
target="_blank"
@@ -1697,7 +1697,7 @@ Object {
>
<a
class="btn btn-link"
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid="
href="https://mattermost.com/pl/about-notifications?utm_source=mattermost&utm_medium=in-product&utm_content=user_settings_notifications&uid=&sid=&edition=team&server_version="
location="user_settings_notifications"
rel="noopener noreferrer"
target="_blank"