diff --git a/server/channels/api4/license.go b/server/channels/api4/license.go index 90e796828e..f08c5ad6a7 100644 --- a/server/channels/api4/license.go +++ b/server/channels/api4/license.go @@ -351,10 +351,8 @@ func requestTrueUpReview(c *Context, w http.ResponseWriter, r *http.Request) { return } - // True-up is only enabled when telemetry is disabled. - // When telemetry is enabled, we already have all the data necessary for true-up reviews to be completed. - telemetryEnabled := c.App.Config().LogSettings.EnableDiagnostics - if telemetryEnabled != nil && !*telemetryEnabled { + // Only report the true up review to CWS if the connection is available. + if err := c.App.Cloud().CheckCWSConnection(c.AppContext.Session().UserId); err == nil { err = c.App.Cloud().SubmitTrueUpReview(c.AppContext.Session().UserId, profileMap) if err != nil { c.Err = model.NewAppError("requestTrueUpReview", "api.license.true_up_review.failed_to_submit", nil, err.Error(), http.StatusInternalServerError) diff --git a/server/channels/api4/license_test.go b/server/channels/api4/license_test.go index df3ceb5493..73af78717b 100644 --- a/server/channels/api4/license_test.go +++ b/server/channels/api4/license_test.go @@ -486,6 +486,7 @@ func TestRequestTrueUpReview(t *testing.T) { cloud := mocks.CloudInterface{} cloud.Mock.On("SubmitTrueUpReview", mock.Anything, mock.Anything).Return(nil) + cloud.Mock.On("CheckCWSConnection", mock.Anything).Return(nil) cloudImpl := th.App.Srv().Cloud defer func() { diff --git a/webapp/channels/src/components/analytics/true_up_review.test.tsx b/webapp/channels/src/components/analytics/true_up_review.test.tsx index 60ef3b1d07..d233b30d58 100644 --- a/webapp/channels/src/components/analytics/true_up_review.test.tsx +++ b/webapp/channels/src/components/analytics/true_up_review.test.tsx @@ -25,7 +25,7 @@ describe('TrueUpReview', () => { IsLicensed: 'true', }), config: { - EnableDiagnostics: 'false', + EnableDiagnostics: 'true', }, }, users: { @@ -55,13 +55,31 @@ describe('TrueUpReview', () => { }, }; - it('regular self hosted license in the true up window sees content', () => { + + it('regular self hosted license (NOT air-gapped) in the true up window sees content', () => { jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => useCWSAvailabilityCheckAll.CSWAvailabilityCheckTypes.Available); renderWithContext(, showsTrueUpReviewState); screen.getByText('Share to Mattermost'); }); + it('regular self hosted license thats air gapped sees download button only', () => { + jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => useCWSAvailabilityCheckAll.CSWAvailabilityCheckTypes.Unavailable); + + renderWithContext(, showsTrueUpReviewState); + screen.getByText('Download Data'); + expect(screen.queryByText('Share to Mattermost')).not.toBeInTheDocument(); + }); + + it('displays the panel regardless of the config value for EnableDiagnostic', () => { + const store = JSON.parse(JSON.stringify(showsTrueUpReviewState)); + store.entities.general.config.EnableDiagnostics = 'false'; + jest.spyOn(useCWSAvailabilityCheckAll, 'default').mockImplementation(() => useCWSAvailabilityCheckAll.CSWAvailabilityCheckTypes.Available); + + renderWithContext(, store); + screen.getByText('Share to Mattermost'); + }); + it('gov sku self-hosted license does not see true up content', () => { const store = JSON.parse(JSON.stringify(showsTrueUpReviewState)); store.entities.general.license.IsGovSku = 'true'; diff --git a/webapp/channels/src/components/analytics/true_up_review.tsx b/webapp/channels/src/components/analytics/true_up_review.tsx index 416b238587..7a5a973cb8 100644 --- a/webapp/channels/src/components/analytics/true_up_review.tsx +++ b/webapp/channels/src/components/analytics/true_up_review.tsx @@ -10,7 +10,7 @@ import {useDispatch, useSelector} from 'react-redux'; import type {GlobalState} from '@mattermost/types/store'; import {isCurrentLicenseCloud} from 'mattermost-redux/selectors/entities/cloud'; -import {getConfig, getLicense} from 'mattermost-redux/selectors/entities/general'; +import {getLicense} from 'mattermost-redux/selectors/entities/general'; import { getSelfHostedErrors, getTrueUpReviewProfile as trueUpReviewProfileSelector, @@ -50,7 +50,6 @@ const TrueUpReview: React.FC = () => { // * are not on starter/free // * are not a government sku const licenseIsTrueUpEligible = isLicensed && !isCloud && !isStarter && !isGovSku; - const telemetryEnabled = useSelector(getConfig).EnableDiagnostics === 'true'; const trueUpReviewError = useSelector((state: GlobalState) => { const errors = getSelfHostedErrors(state); return Boolean(errors.trueUpReview); @@ -70,7 +69,7 @@ const TrueUpReview: React.FC = () => { return; } - if (reviewProfile.getRequestState === 'OK' && isAirGapped && !trueUpReviewError && reviewProfile.content.length > 0) { + if (reviewProfile.getRequestState === 'OK' && !reviewStatus.complete && isAirGapped && !trueUpReviewError && reviewProfile.content.length > 0) { // Create the bundle as a blob containing base64 encoded json data and assign it to a link element. const blob = new Blob([reviewProfile.content], {type: 'application/text'}); const href = URL.createObjectURL(blob); @@ -85,6 +84,7 @@ const TrueUpReview: React.FC = () => { // Remove link and revoke object url to avoid memory leaks. document.body.removeChild(link); URL.revokeObjectURL(href); + dispatch(getTrueUpReviewStatus()); } }, [isAirGapped, reviewProfile, reviewProfile.getRequestState, trueUpReviewError]); @@ -221,10 +221,6 @@ const TrueUpReview: React.FC = () => { return null; } - if (telemetryEnabled) { - return null; - } - pageVisited(TELEMETRY_CATEGORIES.TRUE_UP_REVIEW, 'pageview_true_up_review'); return (