return Promise.resolve({ enabled: false });
}
- const nextSync = this.tasks.find((t: any) =>
+ const nextSync = this.tasks.find((t: Task) =>
[TaskStatuses.InProgress, TaskStatuses.Pending].includes(t.status)
);
const lastSync = this.tasks.find(
- (t: any) => ![TaskStatuses.InProgress, TaskStatuses.Pending].includes(t.status)
+ (t: Task) => ![TaskStatuses.InProgress, TaskStatuses.Pending].includes(t.status)
);
return Promise.resolve({
executionTimeMs: lastSync.executionTimeMs,
summary: lastSync.status === TaskStatuses.Success ? 'Test summary' : undefined,
errorMessage: lastSync.errorMessage,
+ warningMessage: lastSync.warnings?.join() ?? undefined,
}
: undefined,
});
import { FormattedMessage } from 'react-intl';
import Link from '../../components/common/Link';
import CheckIcon from '../../components/icons/CheckIcon';
+import WarningIcon from '../../components/icons/WarningIcon';
import { Alert } from '../../components/ui/Alert';
import { translate, translateWithParameters } from '../../helpers/l10n';
import { useGitHubSyncStatusQuery } from '../../queries/identity-provider';
if (info === undefined) {
return null;
}
- const { finishedAt, errorMessage, status, summary } = info;
+ const { finishedAt, errorMessage, status, summary, warningMessage } = info;
const formattedDate = finishedAt ? formatDistance(new Date(finishedAt), new Date()) : '';
return status === TaskStatuses.Success ? (
<div>
<span className="authentication-enabled spacer-left">
- <CheckIcon className="spacer-right" />
+ {warningMessage ? (
+ <WarningIcon className="spacer-right" />
+ ) : (
+ <CheckIcon className="spacer-right" />
+ )}
</span>
<i>
- {translateWithParameters(
- 'settings.authentication.github.synchronization_successful',
- formattedDate
+ {warningMessage ? (
+ <FormattedMessage
+ id="settings.authentication.github.synchronization_successful.with_warning"
+ defaultMessage={translate(
+ 'settings.authentication.github.synchronization_successful.with_warning'
+ )}
+ values={{
+ date: formattedDate,
+ details: (
+ <Link to="../settings?category=authentication&tab=github">
+ {translate('settings.authentication.github.synchronization_details_link')}
+ </Link>
+ ),
+ }}
+ />
+ ) : (
+ translateWithParameters(
+ 'settings.authentication.github.synchronization_successful',
+ formattedDate
+ )
)}
</i>
</div>
values={{
details: (
<Link to="../settings?category=authentication&tab=github">
- {translate('settings.authentication.github.synchronization_failed_link')}
+ {translate('settings.authentication.github.synchronization_details_link')}
</Link>
),
}}
}
return (
- <Alert
- variant={status === TaskStatuses.Success ? 'success' : 'error'}
- role="alert"
- aria-live="assertive"
- >
- {status === TaskStatuses.Success ? (
- <>
- {translateWithParameters(
- 'settings.authentication.github.synchronization_successful',
- formattedDate
- )}
- <br />
- {summary ?? ''}
- </>
- ) : (
- <React.Fragment key={`synch-alert-${finishedAt}`}>
- <div>
+ <>
+ <Alert
+ variant={status === TaskStatuses.Success ? 'success' : 'error'}
+ role="alert"
+ aria-live="assertive"
+ >
+ {status === TaskStatuses.Success ? (
+ <>
{translateWithParameters(
- 'settings.authentication.github.synchronization_failed',
+ 'settings.authentication.github.synchronization_successful',
formattedDate
)}
- </div>
- <br />
- {errorMessage ?? ''}
- </React.Fragment>
- )}
- </Alert>
+ <br />
+ {summary ?? ''}
+ </>
+ ) : (
+ <React.Fragment key={`synch-alert-${finishedAt}`}>
+ <div>
+ {translateWithParameters(
+ 'settings.authentication.github.synchronization_failed',
+ formattedDate
+ )}
+ </div>
+ <br />
+ {errorMessage ?? ''}
+ </React.Fragment>
+ )}
+ </Alert>
+ <Alert variant="warning" role="alert" aria-live="assertive">
+ {warningMessage}
+ </Alert>
+ </>
);
}
configurationValidityError: byRole('status', {
name: /github.configuration.validation.invalid/,
}),
+ syncWarning: byText(/Warning/),
+ syncSummary: byText(/Test summary/),
configurationValidityWarning: byRole('status', {
name: /github.configuration.validation.valid.short/,
}),
renderAuthentication([Feature.GithubProvisioning]);
await github.enableProvisioning(user);
expect(github.githubProvisioningSuccess.get()).toBeInTheDocument();
- expect(github.githubProvisioningButton.get()).toHaveTextContent('Test summary');
+ expect(github.syncSummary.get()).toBeInTheDocument();
});
it('should display a success status even when another task is pending', async () => {
expect(github.configurationValiditySuccess.get()).toBeInTheDocument();
expect(github.configurationValidityError.query()).not.toBeInTheDocument();
});
+
+ it('should show warning', async () => {
+ handler.addProvisioningTask({
+ status: TaskStatuses.Success,
+ warnings: ['Warning'],
+ });
+ renderAuthentication([Feature.GithubProvisioning]);
+ await github.enableProvisioning(user);
+
+ expect(await github.syncWarning.find()).toBeInTheDocument();
+ expect(github.syncSummary.get()).toBeInTheDocument();
+ });
});
});
githubProvisioningPending: byText(/synchronization_pending/),
githubProvisioningInProgress: byText(/synchronization_in_progress/),
githubProvisioningSuccess: byText(/synchronization_successful/),
+ githubProvisioningWarning: byText(/synchronization_successful.with_warning/),
githubProvisioningAlert: byText(/synchronization_failed_short/),
};
expect(ui.githubProvisioningSuccess.query()).not.toBeInTheDocument();
expect(ui.githubProvisioningInProgress.query()).not.toBeInTheDocument();
});
+
+ it('should display an warning alert', async () => {
+ const warningMessage = 'Very long warning about something that user is not interested in';
+ authenticationHandler.addProvisioningTask({
+ status: TaskStatuses.Success,
+ warnings: [warningMessage],
+ });
+ renderUsersApp([Feature.GithubProvisioning]);
+ await act(async () => expect(await ui.githubProvisioningWarning.find()).toBeInTheDocument());
+ // We don't want to display the full warning message.
+ expect(screen.queryByText(warningMessage)).not.toBeInTheDocument();
+ expect(ui.githubProvisioningWarning.byRole('link').get()).toBeInTheDocument();
+ });
});
});
executionTimeMs: number;
finishedAt: number;
startedAt: number;
+ warningMessage?: string;
} & (
| {
status: TaskStatuses.Success;
settings.authentication.github.synchronization_pending=Synchronization is scheduled.
settings.authentication.github.synchronization_finish=Synchronization is done.
settings.authentication.github.synchronization_successful=Last synchronization was done {0} ago.
+settings.authentication.github.synchronization_successful.with_warning=Last synchronization was done {date} ago with warnings. {details}
settings.authentication.github.synchronization_failed=Last synchronization failed {0} ago.
settings.authentication.github.synchronization_failed_short=Last synchronization failed. {details}
-settings.authentication.github.synchronization_failed_link=More details
+settings.authentication.github.synchronization_details_link=More details
settings.authentication.github.configuration.validation.details=View details
settings.authentication.github.configuration.validation.test=Test configuration
settings.authentication.github.configuration.validation.loading=Checking the configuration