Parcourir la source

SONAR-10346 Display webhook latest delivery status

tags/7.5
Grégoire Aubert il y a 6 ans
Parent
révision
a7cdf1a942

+ 6
- 2
server/sonar-web/src/main/js/apps/webhooks/components/App.tsx Voir le fichier

@@ -37,7 +37,7 @@ interface State {
}

export default class App extends React.PureComponent<Props, State> {
mounted: boolean = false;
mounted = false;
state: State = { loading: true, webhooks: [] };

componentDidMount() {
@@ -65,7 +65,11 @@ export default class App extends React.PureComponent<Props, State> {
};

getScopeParams = ({ organization, component } = this.props) => {
return { organization: organization && organization.key, project: component && component.key };
const organizationKey = organization && organization.key;
return {
organization: component ? component.organization : organizationKey,
project: component && component.key
};
};

handleCreate = (data: { name: string; url: string }) => {

+ 1
- 1
server/sonar-web/src/main/js/apps/webhooks/components/DeliveriesForm.tsx Voir le fichier

@@ -40,7 +40,7 @@ interface State {
const PAGE_SIZE = 10;

export default class DeliveriesForm extends React.PureComponent<Props, State> {
mounted: boolean = false;
mounted = false;
state: State = { deliveries: [], loading: true };

componentDidMount() {

+ 1
- 1
server/sonar-web/src/main/js/apps/webhooks/components/DeliveryItem.tsx Voir le fichier

@@ -40,7 +40,7 @@ interface State {
}

export default class DeliveryItem extends React.PureComponent<Props, State> {
mounted: boolean = false;
mounted = false;
state: State = { loading: false, open: false };

componentDidMount() {

+ 1
- 1
server/sonar-web/src/main/js/apps/webhooks/components/PageActions.tsx Voir le fichier

@@ -35,7 +35,7 @@ interface State {
const WEBHOOKS_LIMIT = 10;

export default class PageActions extends React.PureComponent<Props, State> {
mounted: boolean = false;
mounted = false;
state: State = { openCreate: false };

componentDidMount() {

+ 8
- 7
server/sonar-web/src/main/js/apps/webhooks/components/WebhookActions.tsx Voir le fichier

@@ -40,7 +40,7 @@ interface State {
}

export default class WebhookActions extends React.PureComponent<Props, State> {
mounted: boolean = false;
mounted = false;
state: State = { deliveries: false, updating: false };

componentDidMount() {
@@ -77,18 +77,19 @@ export default class WebhookActions extends React.PureComponent<Props, State> {

render() {
const { webhook } = this.props;
// TODO Disable "Show deliveries" if there is no lastDelivery
return (
<>
<ActionsDropdown className="big-spacer-left">
<ActionsDropdownItem className="js-webhook-update" onClick={this.handleUpdateClick}>
{translate('update_verb')}
</ActionsDropdownItem>
<ActionsDropdownItem
className="js-webhook-deliveries"
onClick={this.handleDeliveriesClick}>
{translate('webhooks.deliveries.show')}
</ActionsDropdownItem>
{webhook.latestDelivery && (
<ActionsDropdownItem
className="js-webhook-deliveries"
onClick={this.handleDeliveriesClick}>
{translate('webhooks.deliveries.show')}
</ActionsDropdownItem>
)}
<ActionsDropdownDivider />
<ConfirmButton
confirmButtonText={translate('delete')}

+ 22
- 1
server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx Voir le fichier

@@ -19,7 +19,11 @@
*/
import * as React from 'react';
import WebhookActions from './WebhookActions';
import { Webhook } from '../../../app/types';
import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
import { Webhook, WebhookDelivery } from '../../../app/types';
import { translate } from '../../../helpers/l10n';

interface Props {
onDelete: (webhook: string) => Promise<void>;
@@ -32,9 +36,26 @@ export default function WebhookItem({ onDelete, onUpdate, webhook }: Props) {
<tr>
<td>{webhook.name}</td>
<td>{webhook.url}</td>
<td>
<LatestDelivery latestDelivery={webhook.latestDelivery} />
</td>
<td className="thin nowrap text-right">
<WebhookActions onDelete={onDelete} onUpdate={onUpdate} webhook={webhook} />
</td>
</tr>
);
}

export function LatestDelivery({ latestDelivery }: { latestDelivery?: WebhookDelivery }) {
if (!latestDelivery) {
return <span>{translate('webhooks.last_execution.none')}</span>;
}
return (
<>
{latestDelivery.success ? <AlertSuccessIcon /> : <AlertErrorIcon />}
<span className="spacer-left">
<DateTimeFormatter date={latestDelivery.at} />
</span>
</>
);
}

+ 1
- 0
server/sonar-web/src/main/js/apps/webhooks/components/WebhooksList.tsx Voir le fichier

@@ -35,6 +35,7 @@ export default class WebhooksList extends React.PureComponent<Props> {
<tr>
<th>{translate('name')}</th>
<th>{translate('webhooks.url')}</th>
<th>{translate('webhooks.last_execution')}</th>
<th />
</tr>
</thead>

+ 4
- 1
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx Voir le fichier

@@ -81,7 +81,10 @@ describe('should correctly fetch webhooks when', () => {
shallow(<App component={component} organization={undefined} />);

await new Promise(setImmediate);
expect(searchWebhooks).toHaveBeenCalledWith({ project: component.key });
expect(searchWebhooks).toHaveBeenCalledWith({
project: component.key,
organization: component.organization
});
});

it('on organization scope', async () => {

+ 1
- 1
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageActions-test.tsx Voir le fichier

@@ -47,5 +47,5 @@ it('should display the create form', () => {
});

function getWrapper(props = {}) {
return shallow(<PageActions onCreate={jest.fn()} loading={false} webhooksCount={5} {...props} />);
return shallow(<PageActions loading={false} onCreate={jest.fn()} webhooksCount={5} {...props} />);
}

+ 15
- 2
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookActions-test.tsx Voir le fichier

@@ -22,7 +22,19 @@ import { shallow } from 'enzyme';
import WebhookActions from '../WebhookActions';
import { click } from '../../../../helpers/testUtils';

const webhook = { key: '1', name: 'foo', url: 'http://foo.bar' };
const webhook = {
key: '1',
name: 'foo',
url: 'http://foo.bar'
};

const delivery = {
at: '12.02.2018',
durationMs: 20,
httpStatus: 200,
id: '2',
success: true
};

it('should render correctly', () => {
expect(getWrapper()).toMatchSnapshot();
@@ -55,7 +67,8 @@ it('should display the delete webhook form', () => {
});

it('should display the deliveries form', () => {
const wrapper = getWrapper();
const wrapper = getWrapper({ webhook: { ...webhook, latestDelivery: delivery } });
expect(wrapper).toMatchSnapshot();
click(wrapper.find('.js-webhook-deliveries'));
expect(wrapper.find('DeliveriesForm').exists()).toBeTruthy();
});

+ 25
- 2
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx Voir le fichier

@@ -19,9 +19,22 @@
*/
import * as React from 'react';
import { shallow } from 'enzyme';
import WebhookItem from '../WebhookItem';
import WebhookItem, { LatestDelivery } from '../WebhookItem';

const webhook = { key: '1', name: 'my webhook', url: 'http://webhook.target' };
const latestDelivery = {
at: '12.02.2018',
durationMs: 20,
httpStatus: 200,
id: '2',
success: true
};

const webhook = {
key: '1',
name: 'my webhook',
url: 'http://webhook.target',
latestDelivery
};

it('should render correctly', () => {
expect(
@@ -34,3 +47,13 @@ it('should render correctly', () => {
)
).toMatchSnapshot();
});

it('should render correctly the latest delivery', () => {
expect(shallow(<LatestDelivery latestDelivery={undefined} />)).toMatchSnapshot();
expect(shallow(<LatestDelivery latestDelivery={latestDelivery} />)).toMatchSnapshot();
expect(
shallow(
<LatestDelivery latestDelivery={{ ...latestDelivery, httpStatus: 500, success: false }} />
)
).toMatchSnapshot();
});

+ 24
- 1
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookActions-test.tsx.snap Voir le fichier

@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render correctly 1`] = `
exports[`should display the deliveries form 1`] = `
<React.Fragment>
<ActionsDropdown
className="big-spacer-left"
@@ -28,3 +28,26 @@ exports[`should render correctly 1`] = `
</ActionsDropdown>
</React.Fragment>
`;

exports[`should render correctly 1`] = `
<React.Fragment>
<ActionsDropdown
className="big-spacer-left"
>
<ActionsDropdownItem
className="js-webhook-update"
onClick={[Function]}
>
update_verb
</ActionsDropdownItem>
<ActionsDropdownDivider />
<ConfirmButton
confirmButtonText="delete"
isDestructive={true}
modalBody="webhooks.delete.confirm.foo"
modalHeader="webhooks.delete"
onConfirm={[Function]}
/>
</ActionsDropdown>
</React.Fragment>
`;

+ 52
- 0
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap Voir le fichier

@@ -8,6 +8,19 @@ exports[`should render correctly 1`] = `
<td>
http://webhook.target
</td>
<td>
<LatestDelivery
latestDelivery={
Object {
"at": "12.02.2018",
"durationMs": 20,
"httpStatus": 200,
"id": "2",
"success": true,
}
}
/>
</td>
<td
className="thin nowrap text-right"
>
@@ -17,6 +30,13 @@ exports[`should render correctly 1`] = `
webhook={
Object {
"key": "1",
"latestDelivery": Object {
"at": "12.02.2018",
"durationMs": 20,
"httpStatus": 200,
"id": "2",
"success": true,
},
"name": "my webhook",
"url": "http://webhook.target",
}
@@ -25,3 +45,35 @@ exports[`should render correctly 1`] = `
</td>
</tr>
`;

exports[`should render correctly the latest delivery 1`] = `
<span>
webhooks.last_execution.none
</span>
`;

exports[`should render correctly the latest delivery 2`] = `
<React.Fragment>
<AlertSuccessIcon />
<span
className="spacer-left"
>
<DateTimeFormatter
date="12.02.2018"
/>
</span>
</React.Fragment>
`;

exports[`should render correctly the latest delivery 3`] = `
<React.Fragment>
<AlertErrorIcon />
<span
className="spacer-left"
>
<DateTimeFormatter
date="12.02.2018"
/>
</span>
</React.Fragment>
`;

+ 3
- 0
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap Voir le fichier

@@ -18,6 +18,9 @@ exports[`should correctly render the webhooks 1`] = `
<th>
webhooks.url
</th>
<th>
webhooks.last_execution
</th>
<th />
</tr>
</thead>

+ 2
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties Voir le fichier

@@ -2824,6 +2824,8 @@ webhooks.delivery.duration_x=Duration: {0}
webhooks.delivery.payload=Payload:
webhooks.delivery.response_x=Response: {0}
webhooks.documentation_link=Webhooks documentation
webhooks.last_execution=Last execution
webhooks.last_execution.none=Never
webhooks.maximum_reached=You reached your maximum number of {0} webhooks. You can still update or delete an existing one.
webhooks.name=Name
webhooks.name.required=Name is required.

Chargement…
Annuler
Enregistrer