import { getJSON, post, RequestData } from 'sonar-ui-common/helpers/request';
import throwGlobalError from '../app/utils/throwGlobalError';
import { IndexationStatus } from '../types/indexation';
+import { Task } from '../types/tasks';
export function getAnalysisStatus(data: {
component: string;
return getJSON('/api/ce/analysis_status', data).catch(throwGlobalError);
}
-export function getActivity(data: RequestData): Promise<{ tasks: T.Task[] }> {
+export function getActivity(data: RequestData): Promise<{ tasks: Task[] }> {
return getJSON('/api/ce/activity', data);
}
return getJSON('/api/ce/activity_status', data);
}
-export function getTask(id: string, additionalFields?: string[]): Promise<T.Task> {
+export function getTask(id: string, additionalFields?: string[]): Promise<Task> {
return getJSON('/api/ce/task', { id, additionalFields }).then(r => r.task);
}
return post('/api/ce/cancel_all');
}
-export function getTasksForComponent(
- component: string
-): Promise<{ queue: T.Task[]; current: T.Task }> {
+export function getTasksForComponent(component: string): Promise<{ queue: Task[]; current: Task }> {
return getJSON('/api/ce/component', { component }).catch(throwGlobalError);
}
import { getAnalysisStatus, getTasksForComponent } from '../../api/ce';
import { getComponentData } from '../../api/components';
import { getComponentNavigation } from '../../api/nav';
-import { STATUSES } from '../../apps/background-tasks/constants';
import { Location, Router, withRouter } from '../../components/hoc/withRouter';
import {
getBranchLikeQuery,
} from '../../store/rootActions';
import { BranchLike } from '../../types/branch-like';
import { isPortfolioLike } from '../../types/component';
+import { Task, TaskStatuses } from '../../types/tasks';
import ComponentContainerNotFound from './ComponentContainerNotFound';
import { ComponentContext } from './ComponentContext';
import PageUnavailableDueToIndexation from './indexation/PageUnavailableDueToIndexation';
branchLike?: BranchLike;
branchLikes: BranchLike[];
component?: T.Component;
- currentTask?: T.Task;
+ currentTask?: Task;
isPending: boolean;
loading: boolean;
- tasksInProgress?: T.Task[];
+ tasksInProgress?: Task[];
warnings: string[];
}
const newCurrentTask = this.getCurrentTask(current, branchLike);
const pendingTasks = this.getPendingTasks(queue, branchLike);
const newTasksInProgress = pendingTasks.filter(
- task => task.status === STATUSES.IN_PROGRESS
+ task => task.status === TaskStatuses.InProgress
);
const currentTaskChanged =
);
}
- const isPending = pendingTasks.some(task => task.status === STATUSES.PENDING);
+ const isPending = pendingTasks.some(task => task.status === TaskStatuses.Pending);
return {
currentTask: newCurrentTask,
isPending,
: branchLikes.find(b => isBranch(b) && (query.branch ? b.name === query.branch : b.isMain));
};
- getCurrentTask = (current: T.Task, branchLike?: BranchLike) => {
+ getCurrentTask = (current: Task, branchLike?: BranchLike) => {
if (!current) {
return undefined;
}
- return current.status === STATUSES.FAILED || this.isSameBranch(current, branchLike)
+ return current.status === TaskStatuses.Failed || this.isSameBranch(current, branchLike)
? current
: undefined;
};
- getPendingTasks = (pendingTasks: T.Task[], branchLike?: BranchLike) => {
+ getPendingTasks = (pendingTasks: Task[], branchLike?: BranchLike) => {
return pendingTasks.filter(task => this.isSameBranch(task, branchLike));
};
- isSameBranch = (task: Pick<T.Task, 'branch' | 'pullRequest'>, branchLike?: BranchLike) => {
+ isSameBranch = (task: Pick<Task, 'branch' | 'pullRequest'>, branchLike?: BranchLike) => {
if (branchLike) {
if (isMainBranch(branchLike)) {
return (!task.pullRequest && !task.branch) || branchLike.name === task.branch;
import { getTasksForComponent } from '../../../api/ce';
import { getComponentData } from '../../../api/components';
import { getComponentNavigation } from '../../../api/nav';
-import { STATUSES } from '../../../apps/background-tasks/constants';
import { mockBranch, mockMainBranch, mockPullRequest } from '../../../helpers/mocks/branch-like';
+import { mockTask } from '../../../helpers/mocks/tasks';
import { mockComponent, mockLocation, mockRouter } from '../../../helpers/testMocks';
import { ComponentQualifier } from '../../../types/component';
+import { TaskStatuses } from '../../../types/tasks';
import { ComponentContainer } from '../ComponentContainer';
import PageUnavailableDueToIndexation from '../indexation/PageUnavailableDueToIndexation';
expect(component.isSameBranch({ branch: 'branch-6.7' }, pullRequest)).toBe(false);
expect(component.isSameBranch({ pullRequest: pullRequest.key }, pullRequest)).toBe(true);
- const currentTask = { pullRequest: pullRequest.key, status: STATUSES.IN_PROGRESS } as T.Task;
- const failedTask = { ...currentTask, status: STATUSES.FAILED };
- const pendingTasks = [currentTask, { branch: branch3.name } as T.Task, {} as T.Task];
+ const currentTask = mockTask({ pullRequest: pullRequest.key, status: TaskStatuses.InProgress });
+ const failedTask = { ...currentTask, status: TaskStatuses.Failed };
+ const pendingTasks = [currentTask, mockTask({ branch: branch3.name }), mockTask()];
expect(component.getCurrentTask(currentTask, undefined)).toBeUndefined();
expect(component.getCurrentTask(failedTask, mainBranch)).toBe(failedTask);
expect(component.getCurrentTask(currentTask, mainBranch)).toBeUndefined();
jest.useFakeTimers();
(getTasksForComponent as jest.Mock<any>)
.mockResolvedValueOnce({
- queue: [{ id: 'foo', status: STATUSES.IN_PROGRESS }]
+ queue: [{ id: 'foo', status: TaskStatuses.InProgress }]
})
.mockResolvedValueOnce({
queue: []
});
(getTasksForComponent as jest.Mock<any>)
.mockResolvedValueOnce({ queue: [] })
- .mockResolvedValueOnce({ queue: [], current: { id: 'foo', status: STATUSES.SUCCESS } });
+ .mockResolvedValueOnce({ queue: [], current: { id: 'foo', status: TaskStatuses.Success } });
const wrapper = shallowRender();
// First round, nothing in the queue, and component navigation was not called
import { Link } from 'react-router';
import { Alert, AlertProps } from 'sonar-ui-common/components/ui/Alert';
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
-import { BackgroundTaskTypes, STATUSES } from '../../../apps/background-tasks/constants';
import { IndexationNotificationType } from '../../../types/indexation';
+import { TaskStatuses, TaskTypes } from '../../../types/tasks';
export interface IndexationNotificationRendererProps {
type: IndexationNotificationType;
to={{
pathname: '/admin/background_tasks',
query: {
- taskType: BackgroundTaskTypes.IssueSync,
- status: hasError ? STATUSES.FAILED : undefined
+ taskType: TaskTypes.IssueSync,
+ status: hasError ? TaskStatuses.Failed : undefined
}
}}>
{text}
import * as classNames from 'classnames';
import * as React from 'react';
import ContextNavBar from 'sonar-ui-common/components/ui/ContextNavBar';
-import { STATUSES } from '../../../../apps/background-tasks/constants';
import { BranchLike } from '../../../../types/branch-like';
import { ComponentQualifier } from '../../../../types/component';
+import { Task, TaskStatuses } from '../../../../types/tasks';
import { rawSizes } from '../../../theme';
import RecentHistory from '../../RecentHistory';
import ComponentNavBgTaskNotif from './ComponentNavBgTaskNotif';
branchLikes: BranchLike[];
currentBranchLike: BranchLike | undefined;
component: T.Component;
- currentTask?: T.Task;
+ currentTask?: Task;
currentTaskOnSameBranch?: boolean;
isInProgress?: boolean;
isPending?: boolean;
}, [component, component.key]);
let notifComponent;
- if (isInProgress || isPending || (currentTask && currentTask.status === STATUSES.FAILED)) {
+ if (isInProgress || isPending || (currentTask && currentTask.status === TaskStatuses.Failed)) {
notifComponent = (
<ComponentNavBgTaskNotif
component={component}
import { hasMessage, translate } from 'sonar-ui-common/helpers/l10n';
import { STATUSES } from '../../../../apps/background-tasks/constants';
import { getComponentBackgroundTaskUrl } from '../../../../helpers/urls';
+import { Task, TaskStatuses } from '../../../../types/tasks';
import ComponentNavLicenseNotif from './ComponentNavLicenseNotif';
interface Props {
component: T.Component;
- currentTask?: T.Task;
+ currentTask?: Task;
currentTaskOnSameBranch?: boolean;
isInProgress?: boolean;
isPending?: boolean;
{this.renderMessage('component_navigation.status.pending', STATUSES.ALL)}
</Alert>
);
- } else if (currentTask && currentTask.status === STATUSES.FAILED) {
+ } else if (currentTask && currentTask.status === TaskStatuses.Failed) {
if (
currentTask.errorType &&
hasMessage('license.component_navigation.button', currentTask.errorType)
import { isValidLicense } from '../../../../api/marketplace';
import { withAppState } from '../../../../components/hoc/withAppState';
import { ComponentQualifier } from '../../../../types/component';
+import { Task } from '../../../../types/tasks';
interface Props {
appState: Pick<T.AppState, 'canAdmin'>;
- currentTask?: T.Task;
+ currentTask?: Task;
}
interface State {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockTask } from '../../../../../helpers/mocks/tasks';
+import { mockComponent } from '../../../../../helpers/testMocks';
+import { TaskStatuses } from '../../../../../types/tasks';
import ComponentNavBgTaskNotif from '../ComponentNavBgTaskNotif';
jest.mock('sonar-ui-common/helpers/l10n', () => ({
hasMessage: jest.fn().mockReturnValue(true)
}));
-const component = {
- analysisDate: '2017-01-02T00:00:00.000Z',
- breadcrumbs: [],
- key: 'foo',
- name: 'Foo',
- organization: 'org',
- qualifier: 'TRK',
- version: '0.0.1'
-};
-
-it('renders background task error correctly', () => {
- expect(getWrapper()).toMatchSnapshot();
-});
-
-it('renders background task error correctly for a different branch/PR', () => {
+it('renders correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(shallowRender({ isPending: true })).toMatchSnapshot('pending');
+ expect(
+ shallowRender({
+ component: mockComponent({ configuration: { showBackgroundTasks: true } }),
+ isPending: true
+ })
+ ).toMatchSnapshot('pending for admins');
+ expect(shallowRender({ isInProgress: true, isPending: true })).toMatchSnapshot('in progress');
+ expect(
+ shallowRender({
+ currentTask: mockTask({
+ status: TaskStatuses.Failed,
+ errorType: 'LICENSING',
+ errorMessage: 'Foo'
+ })
+ })
+ ).toMatchSnapshot('license issue');
expect(
- getWrapper({
- currentTask: { branch: 'my/branch', status: 'FAILED' } as T.Task,
+ shallowRender({
+ currentTask: mockTask({ branch: 'my/branch', status: TaskStatuses.Failed }),
currentTaskOnSameBranch: false
})
- ).toMatchSnapshot();
+ ).toMatchSnapshot('branch');
expect(
- getWrapper({
- currentTask: {
+ shallowRender({
+ currentTask: mockTask({
pullRequest: '650',
pullRequestTitle: 'feature/my_pr',
- status: 'FAILED'
- } as T.Task,
+ status: TaskStatuses.Failed
+ }),
currentTaskOnSameBranch: false
})
- ).toMatchSnapshot();
-});
-
-it('renders background task pending info correctly', () => {
- expect(getWrapper({ isPending: true })).toMatchSnapshot();
-});
-
-it('renders background task pending info correctly for admin', () => {
- expect(
- getWrapper({
- component: { ...component, configuration: { showBackgroundTasks: true } },
- isPending: true
- })
- ).toMatchSnapshot();
-});
-
-it('renders background task in progress info correctly', () => {
- expect(getWrapper({ isInProgress: true, isPending: true })).toMatchSnapshot();
-});
-
-it('renders background task license info correctly', () => {
- expect(
- getWrapper({ currentTask: { status: 'FAILED', errorType: 'LICENSING', errorMessage: 'Foo' } })
- ).toMatchSnapshot();
+ ).toMatchSnapshot('pul request');
+ expect(shallowRender({ currentTask: undefined })).toMatchSnapshot('no current task');
});
-function getWrapper(props = {}) {
- return shallow(
+function shallowRender(props: Partial<ComponentNavBgTaskNotif['props']> = {}) {
+ return shallow<ComponentNavBgTaskNotif>(
<ComponentNavBgTaskNotif
- component={component}
- currentTask={{ status: 'FAILED' } as T.Task}
+ component={mockComponent()}
+ currentTask={mockTask({ status: TaskStatuses.Failed })}
{...props}
/>
);
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { isValidLicense } from '../../../../../api/marketplace';
+import { mockTask } from '../../../../../helpers/mocks/tasks';
+import { TaskStatuses } from '../../../../../types/tasks';
import { ComponentNavLicenseNotif } from '../ComponentNavLicenseNotif';
jest.mock('sonar-ui-common/helpers/l10n', () => ({
it('renders background task license info correctly', async () => {
let wrapper = getWrapper({
- currentTask: { status: 'FAILED', errorType: 'LICENSING', errorMessage: 'Foo' } as T.Task
+ currentTask: mockTask({
+ status: TaskStatuses.Failed,
+ errorType: 'LICENSING',
+ errorMessage: 'Foo'
+ })
});
await waitAndUpdate(wrapper);
expect(wrapper).toMatchSnapshot();
wrapper = getWrapper({
appState: { canAdmin: false },
- currentTask: { status: 'FAILED', errorType: 'LICENSING', errorMessage: 'Foo' } as T.Task
+ currentTask: mockTask({
+ status: TaskStatuses.Failed,
+ errorType: 'LICENSING',
+ errorMessage: 'Foo'
+ })
});
await waitAndUpdate(wrapper);
expect(wrapper).toMatchSnapshot();
it('renders a different message if the license is valid', async () => {
(isValidLicense as jest.Mock<any>).mockResolvedValueOnce({ isValidLicense: true });
const wrapper = getWrapper({
- currentTask: { status: 'FAILED', errorType: 'LICENSING', errorMessage: 'Foo' } as T.Task
+ currentTask: mockTask({
+ status: TaskStatuses.Failed,
+ errorType: 'LICENSING',
+ errorMessage: 'Foo'
+ })
});
await waitAndUpdate(wrapper);
expect(wrapper).toMatchSnapshot();
it('renders correctly for LICENSING_LOC error', async () => {
(isValidLicense as jest.Mock<any>).mockResolvedValueOnce({ isValidLicense: true });
const wrapper = getWrapper({
- currentTask: { status: 'FAILED', errorType: 'LICENSING_LOC', errorMessage: 'Foo' } as T.Task
+ currentTask: mockTask({
+ status: TaskStatuses.Failed,
+ errorType: 'LICENSING_LOC',
+ errorMessage: 'Foo'
+ })
});
await waitAndUpdate(wrapper);
expect(wrapper).toMatchSnapshot();
return shallow(
<ComponentNavLicenseNotif
appState={{ canAdmin: true }}
- currentTask={{ errorMessage: 'Foo', errorType: 'LICENSING' } as T.Task}
+ currentTask={mockTask({ errorMessage: 'Foo', errorType: 'LICENSING' })}
{...props}
/>
);
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`renders background task error correctly 1`] = `
-<Alert
- display="banner"
- variant="error"
->
- <FormattedMessage
- defaultMessage="component_navigation.status.failed_X"
- id="component_navigation.status.failed_X"
- values={
- Object {
- "branch": undefined,
- "type": "background_task.type.",
- "url": undefined,
- }
- }
- />
-</Alert>
-`;
-
-exports[`renders background task error correctly for a different branch/PR 1`] = `
+exports[`renders correctly: branch 1`] = `
<Alert
display="banner"
variant="error"
values={
Object {
"branch": "my/branch",
- "type": "background_task.type.",
+ "type": "background_task.type.REPORT",
"url": undefined,
}
}
</Alert>
`;
-exports[`renders background task error correctly for a different branch/PR 2`] = `
+exports[`renders correctly: default 1`] = `
<Alert
display="banner"
variant="error"
>
<FormattedMessage
- defaultMessage="component_navigation.status.failed_branch_X"
- id="component_navigation.status.failed_branch_X"
+ defaultMessage="component_navigation.status.failed_X"
+ id="component_navigation.status.failed_X"
values={
Object {
- "branch": "650 - feature/my_pr",
- "type": "background_task.type.",
+ "branch": undefined,
+ "type": "background_task.type.REPORT",
"url": undefined,
}
}
</Alert>
`;
-exports[`renders background task in progress info correctly 1`] = `
+exports[`renders correctly: in progress 1`] = `
<Alert
display="banner"
variant="info"
values={
Object {
"branch": undefined,
- "type": "background_task.type.",
+ "type": "background_task.type.REPORT",
"url": undefined,
}
}
</Alert>
`;
-exports[`renders background task license info correctly 1`] = `
+exports[`renders correctly: license issue 1`] = `
<Connect(withAppState(ComponentNavLicenseNotif))
currentTask={
Object {
+ "analysisId": "x123",
+ "componentKey": "foo",
+ "componentName": "Foo",
+ "componentQualifier": "TRK",
"errorMessage": "Foo",
"errorType": "LICENSING",
+ "id": "AXR8jg_0mF2ZsYr8Wzs2",
+ "organization": "bar",
"status": "FAILED",
+ "submittedAt": "2020-09-11T11:45:35+0200",
+ "type": "REPORT",
}
}
/>
`;
-exports[`renders background task pending info correctly 1`] = `
+exports[`renders correctly: no current task 1`] = `""`;
+
+exports[`renders correctly: pending 1`] = `
<Alert
display="banner"
variant="info"
values={
Object {
"branch": undefined,
- "type": "background_task.type.",
+ "type": "background_task.type.REPORT",
"url": undefined,
}
}
</Alert>
`;
-exports[`renders background task pending info correctly for admin 1`] = `
+exports[`renders correctly: pending for admins 1`] = `
<Alert
display="banner"
variant="info"
values={
Object {
"branch": undefined,
- "type": "background_task.type.",
+ "type": "background_task.type.REPORT",
"url": <Link
onlyActiveOnIndex={false}
style={Object {}}
Object {
"pathname": "/project/background_tasks",
"query": Object {
- "id": "foo",
+ "id": "my-project",
"status": "__ALL__",
},
}
/>
</Alert>
`;
+
+exports[`renders correctly: pul request 1`] = `
+<Alert
+ display="banner"
+ variant="error"
+>
+ <FormattedMessage
+ defaultMessage="component_navigation.status.failed_branch_X"
+ id="component_navigation.status.failed_branch_X"
+ values={
+ Object {
+ "branch": "650 - feature/my_pr",
+ "type": "background_task.type.REPORT",
+ "url": undefined,
+ }
+ }
+ />
+</Alert>
+`;
import * as React from 'react';
import { click } from 'sonar-ui-common/helpers/testUtils';
import Search from '../components/Search';
-import { CURRENTS, DEFAULT_FILTERS, STATUSES } from '../constants';
+import { DEFAULT_FILTERS } from '../constants';
import { formatDuration } from '../utils';
-describe('Constants', () => {
- it('should have STATUSES', () => {
- expect(Object.keys(STATUSES).length).toBe(7);
- });
-
- it('should have CURRENTS', () => {
- expect(Object.keys(CURRENTS).length).toBe(2);
- });
-});
-
describe('Search', () => {
const defaultProps: Search['props'] = {
...DEFAULT_FILTERS,
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
import { Location, Router } from '../../../components/hoc/withRouter';
import { fetchOrganizations } from '../../../store/rootActions';
+import { Task, TaskStatuses } from '../../../types/tasks';
import '../background-tasks.css';
-import { CURRENTS, DEBOUNCE_DELAY, DEFAULT_FILTERS, STATUSES } from '../constants';
+import { CURRENTS, DEBOUNCE_DELAY, DEFAULT_FILTERS } from '../constants';
import { mapFiltersToParameters, Query, updateTask } from '../utils';
import Footer from './Footer';
import Header from './Header';
loading: boolean;
pendingCount: number;
pendingTime?: number;
- tasks: T.Task[];
+ tasks: Task[];
types?: string[];
}
});
};
- handleCancelTask = (task: T.Task) => {
+ handleCancelTask = (task: Task) => {
this.setState({ loading: true });
return cancelTaskAPI(task.id).then(nextTask => {
}, this.stopLoading);
};
- handleFilterTask = (task: T.Task) => {
+ handleFilterTask = (task: Task) => {
this.handleFilterUpdate({ query: task.componentKey });
};
handleShowFailing = () => {
this.handleFilterUpdate({
...DEFAULT_FILTERS,
- status: STATUSES.FAILED,
+ status: TaskStatuses.Failed,
currents: CURRENTS.ONLY_CURRENTS
});
};
*/
import * as React from 'react';
import { translateWithParameters } from 'sonar-ui-common/helpers/l10n';
+import { Task } from '../../../types/tasks';
const LIMIT = 1000;
interface Props {
- tasks: T.Task[];
+ tasks: Task[];
}
export default function Footer({ tasks }: Props) {
import Modal from 'sonar-ui-common/components/controls/Modal';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { getTask } from '../../../api/ce';
+import { Task } from '../../../types/tasks';
interface Props {
onClose: () => void;
- task: Pick<T.Task, 'componentName' | 'id' | 'type'>;
+ task: Pick<Task, 'componentName' | 'id' | 'type'>;
}
interface State {
import Modal from 'sonar-ui-common/components/controls/Modal';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { getTask } from '../../../api/ce';
+import { Task } from '../../../types/tasks';
interface Props {
onClose: () => void;
- task: Pick<T.Task, 'componentName' | 'errorMessage' | 'id' | 'type'>;
+ task: Pick<Task, 'componentName' | 'errorMessage' | 'id' | 'type'>;
}
interface State {
import * as React from 'react';
import Select from 'sonar-ui-common/components/controls/Select';
import { translate } from 'sonar-ui-common/helpers/l10n';
+import { TaskStatuses } from '../../../types/tasks';
import { STATUSES } from '../constants';
interface Props {
value: STATUSES.ALL_EXCEPT_PENDING,
label: translate('background_task.status.ALL_EXCEPT_PENDING')
},
- { value: STATUSES.PENDING, label: translate('background_task.status.PENDING') },
- { value: STATUSES.IN_PROGRESS, label: translate('background_task.status.IN_PROGRESS') },
- { value: STATUSES.SUCCESS, label: translate('background_task.status.SUCCESS') },
- { value: STATUSES.FAILED, label: translate('background_task.status.FAILED') },
- { value: STATUSES.CANCELED, label: translate('background_task.status.CANCELED') }
+ { value: TaskStatuses.Pending, label: translate('background_task.status.PENDING') },
+ { value: TaskStatuses.InProgress, label: translate('background_task.status.IN_PROGRESS') },
+ { value: TaskStatuses.Success, label: translate('background_task.status.SUCCESS') },
+ { value: TaskStatuses.Failed, label: translate('background_task.status.FAILED') },
+ { value: TaskStatuses.Canceled, label: translate('background_task.status.CANCELED') }
];
return (
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { Task as ITask } from '../../../types/tasks';
import TaskActions from './TaskActions';
import TaskComponent from './TaskComponent';
import TaskDate from './TaskDate';
interface Props {
component?: unknown;
- onCancelTask: (task: T.Task) => Promise<void>;
- onFilterTask: (task: T.Task) => void;
- task: T.Task;
- previousTask?: T.Task;
+ onCancelTask: (task: ITask) => Promise<void>;
+ onFilterTask: (task: ITask) => void;
+ task: ITask;
+ previousTask?: ITask;
}
export default function Task(props: Props) {
import ConfirmModal from 'sonar-ui-common/components/controls/ConfirmModal';
import { lazyLoadComponent } from 'sonar-ui-common/components/lazyLoadComponent';
import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
-import { STATUSES } from '../constants';
+import { Task, TaskStatuses } from '../../../types/tasks';
import ScannerContext from './ScannerContext';
import Stacktrace from './Stacktrace';
interface Props {
component?: unknown;
- onCancelTask: (task: T.Task) => Promise<void>;
- onFilterTask: (task: T.Task) => void;
- task: T.Task;
+ onCancelTask: (task: Task) => Promise<void>;
+ onFilterTask: (task: Task) => void;
+ task: Task;
}
interface State {
const { component, task } = this.props;
const canFilter = component === undefined;
- const canCancel = task.status === STATUSES.PENDING;
+ const canCancel = task.status === TaskStatuses.Pending;
const canShowStacktrace = task.errorMessage !== undefined;
const canShowWarnings = task.warningCount !== undefined && task.warningCount > 0;
const hasActions =
getPullRequestUrl
} from '../../../helpers/urls';
import { isPortfolioLike } from '../../../types/component';
+import { Task } from '../../../types/tasks';
import TaskType from './TaskType';
interface Props {
- task: T.Task;
+ task: Task;
}
export default function TaskComponent({ task }: Props) {
);
}
-function getTaskComponentUrl(componentKey: string, task: T.Task) {
+function getTaskComponentUrl(componentKey: string, task: Task) {
if (isPortfolioLike(task.componentQualifier)) {
return getPortfolioUrl(componentKey);
} else if (task.branch) {
import * as React from 'react';
import PendingIcon from 'sonar-ui-common/components/icons/PendingIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { STATUSES } from '../constants';
+import { TaskStatuses } from '../../../types/tasks';
interface Props {
status: string;
let inner;
switch (status) {
- case STATUSES.PENDING:
+ case TaskStatuses.Pending:
inner = <PendingIcon />;
break;
- case STATUSES.IN_PROGRESS:
+ case TaskStatuses.InProgress:
inner = <i className="spinner" />;
break;
- case STATUSES.SUCCESS:
+ case TaskStatuses.Success:
inner = (
<span className="badge badge-success">{translate('background_task.status.SUCCESS')}</span>
);
break;
- case STATUSES.FAILED:
+ case TaskStatuses.Failed:
inner = (
<span className="badge badge-error">{translate('background_task.status.FAILED')}</span>
);
break;
- case STATUSES.CANCELED:
+ case TaskStatuses.Canceled:
inner = <span className="badge">{translate('background_task.status.CANCELED')}</span>;
break;
default:
import * as classNames from 'classnames';
import * as React from 'react';
import { translate } from 'sonar-ui-common/helpers/l10n';
+import { Task as ITask } from '../../../types/tasks';
import Task from './Task';
interface Props {
- tasks: T.Task[];
+ tasks: ITask[];
component?: unknown;
loading: boolean;
- onCancelTask: (task: T.Task) => Promise<void>;
- onFilterTask: (task: T.Task) => void;
+ onCancelTask: (task: ITask) => Promise<void>;
+ onFilterTask: (task: ITask) => void;
}
export default function Tasks({ tasks, component, loading, onCancelTask, onFilterTask }: Props) {
import { shallow } from 'enzyme';
import * as React from 'react';
import { click } from 'sonar-ui-common/helpers/testUtils';
+import { mockTask } from '../../../../helpers/mocks/tasks';
+import { TaskTypes } from '../../../../types/tasks';
import ScannerContext from '../ScannerContext';
jest.mock('../../../../api/ce', () => ({
const getTask = require('../../../../api/ce').getTask as jest.Mock<any>;
-const task = {
+const task = mockTask({
componentName: 'foo',
id: '123',
- type: 'REPORT'
-};
+ type: TaskTypes.Report
+});
beforeEach(() => {
getTask.mockClear();
import { shallow } from 'enzyme';
import * as React from 'react';
import { click } from 'sonar-ui-common/helpers/testUtils';
+import { mockTask } from '../../../../helpers/mocks/tasks';
+import { TaskTypes } from '../../../../types/tasks';
import Stacktrace from '../Stacktrace';
jest.mock('../../../../api/ce', () => ({
const getTask = require('../../../../api/ce').getTask as jest.Mock<any>;
-const task = {
+const task = mockTask({
componentName: 'foo',
id: '123',
- type: 'REPORT'
-};
+ type: TaskTypes.Report
+});
beforeEach(() => {
getTask.mockClear();
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockTask } from '../../../../helpers/mocks/tasks';
import Task from '../Task';
it('renders', () => {
expect(
- shallow(
- <Task
- onCancelTask={jest.fn()}
- onFilterTask={jest.fn()}
- task={{
- componentName: 'foo',
- id: '123',
- organization: 'org',
- status: 'PENDING',
- submittedAt: '2017-01-01',
- submitterLogin: 'yoda',
- type: 'REPORT'
- }}
- />
- )
+ shallow(<Task onCancelTask={jest.fn()} onFilterTask={jest.fn()} task={mockTask()} />)
).toMatchSnapshot();
});
import { shallow } from 'enzyme';
import * as React from 'react';
import { click } from 'sonar-ui-common/helpers/testUtils';
+import { mockTask } from '../../../../helpers/mocks/tasks';
+import { Task, TaskStatuses } from '../../../../types/tasks';
import TaskActions from '../TaskActions';
it('renders', () => {
expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ status: 'SUCCESS' })).toMatchSnapshot();
+ expect(shallowRender({ status: TaskStatuses.Success })).toMatchSnapshot();
expect(shallowRender({ hasScannerContext: true })).toMatchSnapshot();
expect(shallowRender({ errorMessage: 'error!' })).toMatchSnapshot();
expect(shallowRender({}, { component: { key: 'foo' } })).toMatchSnapshot();
expect(wrapper.find('AnalysisWarningsModal').exists()).toBe(false);
});
-function shallowRender(fields?: Partial<T.Task>, props?: Partial<TaskActions['props']>) {
+function shallowRender(fields?: Partial<Task>, props?: Partial<TaskActions['props']>) {
return shallow(
<TaskActions
onCancelTask={jest.fn()}
onFilterTask={jest.fn()}
- task={{
- componentName: 'foo',
- status: 'PENDING',
- id: '123',
- organization: 'org',
- submittedAt: '2017-01-01',
- type: 'REPORT',
- ...fields
- }}
+ task={mockTask({ ...fields })}
{...props}
/>
);
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockTask } from '../../../../helpers/mocks/tasks';
import { ComponentQualifier } from '../../../../types/component';
+import { Task } from '../../../../types/tasks';
import TaskComponent from '../TaskComponent';
it('renders correctly', () => {
expect(shallowRender({ pullRequest: 'pr-89' })).toMatchSnapshot('pull request');
});
-function shallowRender(taskOverrides: Partial<T.Task> = {}) {
- const TASK = {
- componentKey: 'foo',
- componentName: 'foo',
- componentQualifier: 'TRK',
- id: 'bar',
- organization: 'org',
- status: 'PENDING',
- submittedAt: '2017-01-01',
- submitterLogin: 'yoda',
- type: 'REPORT'
- };
- return shallow(<TaskComponent task={{ ...TASK, ...taskOverrides }} />);
+function shallowRender(taskOverrides: Partial<Task> = {}) {
+ return shallow(<TaskComponent task={mockTask({ ...taskOverrides })} />);
}
<TaskComponent
task={
Object {
- "componentName": "foo",
- "id": "123",
- "organization": "org",
+ "analysisId": "x123",
+ "componentKey": "foo",
+ "componentName": "Foo",
+ "componentQualifier": "TRK",
+ "id": "AXR8jg_0mF2ZsYr8Wzs2",
+ "organization": "bar",
"status": "PENDING",
- "submittedAt": "2017-01-01",
- "submitterLogin": "yoda",
+ "submittedAt": "2020-09-11T11:45:35+0200",
"type": "REPORT",
}
}
/>
<TaskId
- id="123"
- />
- <TaskSubmitter
- submitter="yoda"
+ id="AXR8jg_0mF2ZsYr8Wzs2"
/>
+ <TaskSubmitter />
<TaskDay
- submittedAt="2017-01-01"
+ submittedAt="2020-09-11T11:45:35+0200"
/>
<TaskDate
- date="2017-01-01"
+ date="2020-09-11T11:45:35+0200"
/>
<TaskDate
- baseDate="2017-01-01"
+ baseDate="2020-09-11T11:45:35+0200"
/>
<TaskDate
- baseDate="2017-01-01"
+ baseDate="2020-09-11T11:45:35+0200"
/>
<TaskExecutionTime />
<TaskActions
onFilterTask={[MockFunction]}
task={
Object {
- "componentName": "foo",
- "id": "123",
- "organization": "org",
+ "analysisId": "x123",
+ "componentKey": "foo",
+ "componentName": "Foo",
+ "componentQualifier": "TRK",
+ "id": "AXR8jg_0mF2ZsYr8Wzs2",
+ "organization": "bar",
"status": "PENDING",
- "submittedAt": "2017-01-01",
- "submitterLogin": "yoda",
+ "submittedAt": "2020-09-11T11:45:35+0200",
"type": "REPORT",
}
}
className="js-task-filter"
onClick={[Function]}
>
- background_tasks.filter_by_component_x.foo
+ background_tasks.filter_by_component_x.Foo
</ActionsDropdownItem>
<ActionsDropdownItem
className="js-task-cancel"
className="js-task-filter"
onClick={[Function]}
>
- background_tasks.filter_by_component_x.foo
+ background_tasks.filter_by_component_x.Foo
</ActionsDropdownItem>
</ActionsDropdown>
</td>
className="js-task-filter"
onClick={[Function]}
>
- background_tasks.filter_by_component_x.foo
+ background_tasks.filter_by_component_x.Foo
</ActionsDropdownItem>
<ActionsDropdownItem
className="js-task-cancel"
className="js-task-filter"
onClick={[Function]}
>
- background_tasks.filter_by_component_x.foo
+ background_tasks.filter_by_component_x.Foo
</ActionsDropdownItem>
<ActionsDropdownItem
className="js-task-cancel"
onClose={[Function]}
task={
Object {
- "componentName": "foo",
+ "analysisId": "x123",
+ "componentKey": "foo",
+ "componentName": "Foo",
+ "componentQualifier": "TRK",
"hasScannerContext": true,
- "id": "123",
- "organization": "org",
+ "id": "AXR8jg_0mF2ZsYr8Wzs2",
+ "organization": "bar",
"status": "PENDING",
- "submittedAt": "2017-01-01",
+ "submittedAt": "2020-09-11T11:45:35+0200",
"type": "REPORT",
}
}
onClose={[Function]}
task={
Object {
- "componentName": "foo",
+ "analysisId": "x123",
+ "componentKey": "foo",
+ "componentName": "Foo",
+ "componentQualifier": "TRK",
"errorMessage": "error!",
- "id": "123",
- "organization": "org",
+ "id": "AXR8jg_0mF2ZsYr8Wzs2",
+ "organization": "bar",
"status": "PENDING",
- "submittedAt": "2017-01-01",
+ "submittedAt": "2020-09-11T11:45:35+0200",
"type": "REPORT",
}
}
exports[`shows warnings 1`] = `
<AnalysisWarningsModal
onClose={[Function]}
- taskId="123"
+ taskId="AXR8jg_0mF2ZsYr8Wzs2"
/>
`;
/>
</span>
<Connect(Organization)
- organizationKey="org"
+ organizationKey="bar"
/>
<Link
className="spacer-right"
}
}
>
- foo
+ Foo
</Link>
<TaskType
type="REPORT"
className="little-spacer-right"
/>
<Connect(Organization)
- organizationKey="org"
+ organizationKey="bar"
/>
<Link
className="spacer-right"
}
}
>
- foo
+ Foo
<span
className="text-limited text-text-top"
title="feature"
className="little-spacer-right"
/>
<Connect(Organization)
- organizationKey="org"
+ organizationKey="bar"
/>
<Link
className="spacer-right"
}
}
>
- foo
+ Foo
<span
className="text-limited text-text-top"
title="branch-6.7"
/>
</span>
<Connect(Organization)
- organizationKey="org"
+ organizationKey="bar"
/>
<Link
className="spacer-right"
}
}
>
- foo
+ Foo
</Link>
<TaskType
type="REPORT"
className="little-spacer-right"
/>
<Connect(Organization)
- organizationKey="org"
+ organizationKey="bar"
/>
<Link
className="spacer-right"
}
}
>
- foo
+ Foo
<span
className="text-limited text-text-top"
>
<span
className="note"
>
- bar
+ AXR8jg_0mF2ZsYr8Wzs2
</span>
<TaskType
type="REPORT"
export const STATUSES = {
ALL: '__ALL__',
- ALL_EXCEPT_PENDING: '__ALL_EXCEPT_PENDING__',
- PENDING: 'PENDING',
- IN_PROGRESS: 'IN_PROGRESS',
- SUCCESS: 'SUCCESS',
- FAILED: 'FAILED',
- CANCELED: 'CANCELED'
+ ALL_EXCEPT_PENDING: '__ALL_EXCEPT_PENDING__'
};
-export enum BackgroundTaskTypes {
- Report = 'REPORT',
- IssueSync = 'ISSUE_SYNC'
-}
-
export const ALL_TYPES = 'ALL_TYPES';
export const CURRENTS = {
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { toShortNotSoISOString } from 'sonar-ui-common/helpers/dates';
+import { Task, TaskStatuses } from '../../types/tasks';
import { ALL_TYPES, CURRENTS, STATUSES } from './constants';
export interface Query {
taskType: string;
}
-export function updateTask(tasks: T.Task[], newTask: T.Task) {
+export function updateTask(tasks: Task[], newTask: Task) {
return tasks.map(task => (task.id === newTask.id ? newTask : task));
}
if (filters.status === STATUSES.ALL) {
parameters.status = [
- STATUSES.PENDING,
- STATUSES.IN_PROGRESS,
- STATUSES.SUCCESS,
- STATUSES.FAILED,
- STATUSES.CANCELED
+ TaskStatuses.Pending,
+ TaskStatuses.InProgress,
+ TaskStatuses.Success,
+ TaskStatuses.Failed,
+ TaskStatuses.Canceled
].join();
} else if (filters.status === STATUSES.ALL_EXCEPT_PENDING) {
parameters.status = [
- STATUSES.IN_PROGRESS,
- STATUSES.SUCCESS,
- STATUSES.FAILED,
- STATUSES.CANCELED
+ TaskStatuses.InProgress,
+ TaskStatuses.Success,
+ TaskStatuses.Failed,
+ TaskStatuses.Canceled
].join();
} else {
parameters.status = filters.status;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import { ComponentQualifier } from '../../types/component';
+import { Task, TaskStatuses, TaskTypes } from '../../types/tasks';
+
+export function mockTask(overrides: Partial<Task> = {}): Task {
+ return {
+ analysisId: 'x123',
+ componentKey: 'foo',
+ componentName: 'Foo',
+ componentQualifier: ComponentQualifier.Project,
+ id: 'AXR8jg_0mF2ZsYr8Wzs2',
+ organization: 'bar',
+ status: TaskStatuses.Pending,
+ submittedAt: '2020-09-11T11:45:35+0200',
+ type: TaskTypes.Report,
+ ...overrides
+ };
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+export enum TaskTypes {
+ Report = 'REPORT',
+ IssueSync = 'ISSUE_SYNC'
+}
+
+export enum TaskStatuses {
+ Pending = 'PENDING',
+ InProgress = 'IN_PROGRESS',
+ Success = 'SUCCESS',
+ Failed = 'FAILED',
+ Canceled = 'CANCELED'
+}
+
+export interface Task {
+ analysisId?: string;
+ branch?: string;
+ componentKey?: string;
+ componentName?: string;
+ componentQualifier?: string;
+ errorMessage?: string;
+ errorStacktrace?: string;
+ errorType?: string;
+ executedAt?: string;
+ executionTimeMs?: number;
+ hasErrorStacktrace?: boolean;
+ hasScannerContext?: boolean;
+ id: string;
+ logs?: boolean;
+ organization: string;
+ pullRequest?: string;
+ pullRequestTitle?: string;
+ scannerContext?: string;
+ startedAt?: string;
+ status: TaskStatuses;
+ submittedAt: string;
+ submitterLogin?: string;
+ type: TaskTypes;
+ warningCount?: number;
+ warnings?: string[];
+}
| 'DB_MIGRATION_NEEDED'
| 'DB_MIGRATION_RUNNING';
- export interface Task {
- analysisId?: string;
- branch?: string;
- componentKey?: string;
- componentName?: string;
- componentQualifier?: string;
- errorMessage?: string;
- errorStacktrace?: string;
- errorType?: string;
- executedAt?: string;
- executionTimeMs?: number;
- hasErrorStacktrace?: boolean;
- hasScannerContext?: boolean;
- id: string;
- logs?: boolean;
- organization: string;
- pullRequest?: string;
- pullRequestTitle?: string;
- scannerContext?: string;
- startedAt?: string;
- status: string;
- submittedAt: string;
- submitterLogin?: string;
- type: string;
- warningCount?: number;
- warnings?: string[];
- }
-
export interface TestCase {
coveredLines: number;
durationInMs: number;