From 06feeac0dccc9491021fee7f57385b1ac8012a91 Mon Sep 17 00:00:00 2001 From: Grégoire Aubert Date: Mon, 19 Feb 2018 15:30:33 +0100 Subject: SONAR-10346 Add a shortcut to display the latest delivery of a webhook --- .../qa/util/pageobjects/WebhooksPage.java | 2 +- server/sonar-web/src/main/js/app/types.ts | 18 +-- .../js/apps/webhooks/components/DeliveriesForm.tsx | 5 +- .../apps/webhooks/components/DeliveryAccordion.tsx | 107 +++++++++++++++ .../js/apps/webhooks/components/DeliveryItem.tsx | 114 ++++------------ .../webhooks/components/LatestDeliveryForm.tsx | 98 ++++++++++++++ .../js/apps/webhooks/components/WebhookItem.tsx | 23 +--- .../components/WebhookItemLatestDelivery.tsx | 91 +++++++++++++ .../__tests__/DeliveryAccordion-test.tsx | 58 ++++++++ .../components/__tests__/DeliveryItem-test.tsx | 36 +++-- .../__tests__/LatestDeliveryForm-test.tsx | 61 +++++++++ .../components/__tests__/WebhookItem-test.tsx | 23 +--- .../__tests__/WebhookItemLatestDelivery-test.tsx | 67 +++++++++ .../__snapshots__/DeliveriesForm-test.tsx.snap | 5 +- .../__snapshots__/DeliveryAccordion-test.tsx.snap | 56 ++++++++ .../__snapshots__/DeliveryItem-test.tsx.snap | 150 +++++++++++---------- .../__snapshots__/LatestDeliveryForm-test.tsx.snap | 80 +++++++++++ .../__snapshots__/WebhookItem-test.tsx.snap | 51 +------ .../WebhookItemLatestDelivery-test.tsx.snap | 49 +++++++ .../src/main/js/components/controls/ListFooter.tsx | 9 +- .../main/resources/org/sonar/l10n/core.properties | 4 +- 21 files changed, 823 insertions(+), 284 deletions(-) create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/DeliveryAccordion.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/LatestDeliveryForm.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/WebhookItemLatestDelivery.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryAccordion-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/LatestDeliveryForm-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItemLatestDelivery-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveryAccordion-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/LatestDeliveryForm-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItemLatestDelivery-test.tsx.snap diff --git a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/WebhooksPage.java b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/WebhooksPage.java index bca17a54cb6..1e5a225cd48 100644 --- a/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/WebhooksPage.java +++ b/server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/WebhooksPage.java @@ -92,7 +92,7 @@ public class WebhooksPage { SelenideElement webhook = getWebhook(webhookName); webhook.$(".dropdown-toggle").shouldBe(visible).click(); webhook.$(".js-webhook-deliveries").shouldBe(visible).click(); - modalShouldBeOpen("Recent deliveries for " + webhookName); + modalShouldBeOpen("Recent deliveries of " + webhookName); return new DeliveriesForm($(".modal-body")); } diff --git a/server/sonar-web/src/main/js/app/types.ts b/server/sonar-web/src/main/js/app/types.ts index 43f2c58bad5..c2fe0d91b1c 100644 --- a/server/sonar-web/src/main/js/app/types.ts +++ b/server/sonar-web/src/main/js/app/types.ts @@ -385,16 +385,16 @@ export enum Visibility { } export interface Webhook { - key: string; - latestDelivery?: WebhookDelivery; - name: string; - url: string; + key: string; + latestDelivery?: WebhookDelivery; + name: string; + url: string; } export interface WebhookDelivery { - at: string; - durationMs: number; - httpStatus: number; - id: string; - success: boolean; + at: string; + durationMs: number; + httpStatus?: number; + id: string; + success: boolean; } diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/DeliveriesForm.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/DeliveriesForm.tsx index ce12280de2f..be4c4df298e 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/DeliveriesForm.tsx +++ b/server/sonar-web/src/main/js/apps/webhooks/components/DeliveriesForm.tsx @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import DeliveryItem from './DeliveryItem'; +import DeliveryAccordion from './DeliveryAccordion'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; import ListFooter from '../../../components/controls/ListFooter'; import Modal from '../../../components/controls/Modal'; @@ -96,12 +96,13 @@ export default class DeliveriesForm extends React.PureComponent {

{header}

- {deliveries.map(delivery => )} + {deliveries.map(delivery => )}
{paging !== undefined && ( { + mounted = false; + state: State = { loading: false, open: false }; + + componentDidMount() { + this.mounted = true; + } + + componentWillUnmount() { + this.mounted = false; + } + + fetchPayload = ({ delivery } = this.props) => { + this.setState({ loading: true }); + return getDelivery({ deliveryId: delivery.id }).then( + ({ delivery }) => { + if (this.mounted) { + this.setState({ payload: delivery.payload, loading: false }); + } + }, + () => { + if (this.mounted) { + this.setState({ loading: false }); + } + } + ); + }; + + formatPayload = (payload: string) => { + try { + return JSON.stringify(JSON.parse(payload), undefined, 2); + } catch (error) { + return payload; + } + }; + + handleClick = () => { + if (!this.state.payload) { + this.fetchPayload(); + } + this.setState(({ open }) => ({ open: !open })); + }; + + render() { + const { delivery } = this.props; + const { loading, open, payload } = this.state; + + return ( + + delivery.success ? ( + + ) : ( + + ) + } + title={}> + + + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/DeliveryItem.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/DeliveryItem.tsx index cd75390ec0f..06f661468dd 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/DeliveryItem.tsx +++ b/server/sonar-web/src/main/js/apps/webhooks/components/DeliveryItem.tsx @@ -18,102 +18,46 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon'; -import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon'; -import DateTimeFormatter from '../../../components/intl/DateTimeFormatter'; -import BoxedGroupAccordion from '../../../components/controls/BoxedGroupAccordion'; import CodeSnippet from '../../../components/common/CodeSnippet'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; -import { getDelivery } from '../../../api/webhooks'; import { formatMeasure } from '../../../helpers/measures'; import { translateWithParameters, translate } from '../../../helpers/l10n'; import { WebhookDelivery } from '../../../app/types'; interface Props { + className?: string; delivery: WebhookDelivery; -} - -interface State { loading: boolean; - open: boolean; - payload?: string; + payload: string | undefined; } -export default class DeliveryItem extends React.PureComponent { - mounted = false; - state: State = { loading: false, open: false }; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - fetchPayload = ({ delivery } = this.props) => { - this.setState({ loading: true }); - return getDelivery({ deliveryId: delivery.id }).then( - ({ delivery }) => { - if (this.mounted) { - this.setState({ payload: delivery.payload, loading: false }); - } - }, - () => { - if (this.mounted) { - this.setState({ loading: false }); - } - } - ); - }; - - formatPayload = (payload: string) => { - try { - return JSON.stringify(JSON.parse(payload), undefined, 2); - } catch (error) { - return payload; - } - }; - - handleClick = () => { - if (!this.state.payload) { - this.fetchPayload(); - } - this.setState(({ open }) => ({ open: !open })); - }; - - render() { - const { delivery } = this.props; - const { loading, open, payload } = this.state; +export default function DeliveryItem({ className, delivery, loading, payload }: Props) { + return ( +
+

+ {translateWithParameters( + 'webhooks.delivery.response_x', + delivery.httpStatus || translate('webhooks.delivery.server_unreachable') + )} +

+

+ {translateWithParameters( + 'webhooks.delivery.duration_x', + formatMeasure(delivery.durationMs, 'MILLISEC') + )} +

+

{translate('webhooks.delivery.payload')}

+ + {payload && } + +
+ ); +} - return ( - - delivery.success ? ( - - ) : ( - - ) - } - title={}> -
-

- {translateWithParameters('webhooks.delivery.response_x', delivery.httpStatus)} -

-

- {translateWithParameters( - 'webhooks.delivery.duration_x', - formatMeasure(delivery.durationMs, 'MILLISEC') - )} -

-

{translate('webhooks.delivery.payload')}

- - {payload && } - -
-
- ); +function formatPayload(payload: string) { + try { + return JSON.stringify(JSON.parse(payload), undefined, 2); + } catch (error) { + return payload; } } diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/LatestDeliveryForm.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/LatestDeliveryForm.tsx new file mode 100644 index 00000000000..ef4bbe178cb --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/LatestDeliveryForm.tsx @@ -0,0 +1,98 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 * as React from 'react'; +import DeliveryItem from './DeliveryItem'; +import Modal from '../../../components/controls/Modal'; +import { Webhook, WebhookDelivery } from '../../../app/types'; +import { translateWithParameters, translate } from '../../../helpers/l10n'; +import { getDelivery } from '../../../api/webhooks'; + +interface Props { + delivery: WebhookDelivery; + onClose: () => void; + webhook: Webhook; +} + +interface State { + loading: boolean; + payload?: string; +} + +export default class LatestDeliveryForm extends React.PureComponent { + mounted = false; + state: State = { loading: true }; + + componentDidMount() { + this.mounted = true; + this.fetchPayload(); + } + + componentWillUnmount() { + this.mounted = false; + } + + fetchPayload = ({ delivery } = this.props) => { + return getDelivery({ deliveryId: delivery.id }).then( + ({ delivery }) => { + if (this.mounted) { + this.setState({ payload: delivery.payload, loading: false }); + } + }, + () => { + if (this.mounted) { + this.setState({ loading: false }); + } + } + ); + }; + + formatPayload = (payload: string) => { + try { + return JSON.stringify(JSON.parse(payload), undefined, 2); + } catch (error) { + return payload; + } + }; + + render() { + const { delivery, webhook } = this.props; + const { loading, payload } = this.state; + const header = translateWithParameters('webhooks.latest_delivery_for_x', webhook.name); + + return ( + +
+

{header}

+
+ +
+ +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx index 5016508e13c..3bd7e4aa4b2 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx +++ b/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx @@ -18,12 +18,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; +import WebhookItemLatestDelivery from './WebhookItemLatestDelivery'; import WebhookActions from './WebhookActions'; -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'; +import { Webhook } from '../../../app/types'; interface Props { onDelete: (webhook: string) => Promise; @@ -37,7 +34,7 @@ export default function WebhookItem({ onDelete, onUpdate, webhook }: Props) { {webhook.name} {webhook.url} - + @@ -45,17 +42,3 @@ export default function WebhookItem({ onDelete, onUpdate, webhook }: Props) { ); } - -export function LatestDelivery({ latestDelivery }: { latestDelivery?: WebhookDelivery }) { - if (!latestDelivery) { - return {translate('webhooks.last_execution.none')}; - } - return ( - <> - {latestDelivery.success ? : } - - - - - ); -} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItemLatestDelivery.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItemLatestDelivery.tsx new file mode 100644 index 00000000000..417790dddeb --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItemLatestDelivery.tsx @@ -0,0 +1,91 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 * as React from 'react'; +import LatestDeliveryForm from './LatestDeliveryForm'; +import BulletListIcon from '../../../components/icons-components/BulletListIcon'; +import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon'; +import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon'; +import DateTimeFormatter from '../../../components/intl/DateTimeFormatter'; +import { ButtonIcon } from '../../../components/ui/buttons'; +import { Webhook } from '../../../app/types'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + webhook: Webhook; +} + +interface State { + modal: boolean; +} + +export default class WebhookItemLatestDelivery extends React.PureComponent { + mounted = false; + state: State = { modal: false }; + + componentDidMount() { + this.mounted = true; + } + + componentWillUnmount() { + this.mounted = false; + } + + handleClick = () => { + this.setState({ modal: true }); + }; + + handleModalClose = () => { + if (this.mounted) { + this.setState({ modal: false }); + } + }; + + render() { + const { webhook } = this.props; + if (!webhook.latestDelivery) { + return {translate('webhooks.last_execution.none')}; + } + + const { modal } = this.state; + return ( + <> + {webhook.latestDelivery.success ? ( + + ) : ( + + )} + + + + + + + + {modal && ( + + )} + + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryAccordion-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryAccordion-test.tsx new file mode 100644 index 00000000000..47aab5ee108 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryAccordion-test.tsx @@ -0,0 +1,58 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 * as React from 'react'; +import { shallow } from 'enzyme'; +import DeliveryAccordion from '../DeliveryAccordion'; +import { getDelivery } from '../../../../api/webhooks'; + +jest.mock('../../../../api/webhooks', () => ({ + getDelivery: jest.fn(() => + Promise.resolve({ + delivery: { payload: '{ "success": true }' } + }) + ) +})); + +const delivery = { + at: '12.02.2018', + durationMs: 20, + httpStatus: 200, + id: '2', + success: true +}; + +beforeEach(() => { + (getDelivery as jest.Mock).mockClear(); +}); + +it('should render correctly', async () => { + const wrapper = getWrapper(); + expect(wrapper).toMatchSnapshot(); + + wrapper.find('BoxedGroupAccordion').prop('onClick')(); + await new Promise(setImmediate); + expect(getDelivery).lastCalledWith({ deliveryId: delivery.id }); + wrapper.update(); + expect(wrapper).toMatchSnapshot(); +}); + +function getWrapper(props = {}) { + return shallow(); +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryItem-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryItem-test.tsx index 585df65cab5..f9a912b73ce 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryItem-test.tsx +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryItem-test.tsx @@ -20,15 +20,6 @@ import * as React from 'react'; import { shallow } from 'enzyme'; import DeliveryItem from '../DeliveryItem'; -import { getDelivery } from '../../../../api/webhooks'; - -jest.mock('../../../../api/webhooks', () => ({ - getDelivery: jest.fn(() => - Promise.resolve({ - delivery: { payload: '{ "success": true }' } - }) - ) -})); const delivery = { at: '12.02.2018', @@ -38,21 +29,26 @@ const delivery = { success: true }; -beforeEach(() => { - (getDelivery as jest.Mock).mockClear(); -}); - -it('should render correctly', async () => { +it('should render correctly', () => { const wrapper = getWrapper(); expect(wrapper).toMatchSnapshot(); +}); - wrapper.find('BoxedGroupAccordion').prop('onClick')(); - await new Promise(setImmediate); - expect(getDelivery).lastCalledWith({ deliveryId: delivery.id }); - wrapper.update(); - expect(wrapper).toMatchSnapshot(); +it('should render correctly when no payload', () => { + expect(getWrapper({ loading: true, payload: undefined })).toMatchSnapshot(); +}); + +it('should render correctly when no http status', () => { + expect(getWrapper({ delivery: { ...delivery, httpStatus: undefined } })).toMatchSnapshot(); }); function getWrapper(props = {}) { - return shallow(); + return shallow( + + ); } diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/LatestDeliveryForm-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/LatestDeliveryForm-test.tsx new file mode 100644 index 00000000000..6df63daca71 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/LatestDeliveryForm-test.tsx @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 * as React from 'react'; +import { shallow } from 'enzyme'; +import LatestDeliveryForm from '../LatestDeliveryForm'; +import { getDelivery } from '../../../../api/webhooks'; + +jest.mock('../../../../api/webhooks', () => ({ + getDelivery: jest.fn(() => + Promise.resolve({ + delivery: { payload: '{ "success": true }' } + }) + ) +})); + +const delivery = { + at: '12.02.2018', + durationMs: 20, + httpStatus: 200, + id: '2', + success: true +}; + +const webhook = { key: '1', name: 'foo', url: 'http://foo.bar' }; + +beforeEach(() => { + (getDelivery as jest.Mock).mockClear(); +}); + +it('should render correctly', async () => { + const wrapper = getWrapper(); + expect(wrapper).toMatchSnapshot(); + + await new Promise(setImmediate); + expect(getDelivery).lastCalledWith({ deliveryId: delivery.id }); + wrapper.update(); + expect(wrapper).toMatchSnapshot(); +}); + +function getWrapper(props = {}) { + return shallow( + + ); +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx index 6861daae1d2..06335817f04 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx @@ -19,21 +19,12 @@ */ import * as React from 'react'; import { shallow } from 'enzyme'; -import WebhookItem, { LatestDelivery } from '../WebhookItem'; - -const latestDelivery = { - at: '12.02.2018', - durationMs: 20, - httpStatus: 200, - id: '2', - success: true -}; +import WebhookItem from '../WebhookItem'; const webhook = { key: '1', name: 'my webhook', - url: 'http://webhook.target', - latestDelivery + url: 'http://webhook.target' }; it('should render correctly', () => { @@ -47,13 +38,3 @@ it('should render correctly', () => { ) ).toMatchSnapshot(); }); - -it('should render correctly the latest delivery', () => { - expect(shallow()).toMatchSnapshot(); - expect(shallow()).toMatchSnapshot(); - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItemLatestDelivery-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItemLatestDelivery-test.tsx new file mode 100644 index 00000000000..a705c21801c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItemLatestDelivery-test.tsx @@ -0,0 +1,67 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 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 * as React from 'react'; +import { shallow } from 'enzyme'; +import WebhookItemLatestDelivery from '../WebhookItemLatestDelivery'; +import { click } from '../../../../helpers/testUtils'; + +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 a success delivery', () => { + expect(shallow()).toMatchSnapshot(); +}); + +it('should render correctly when no latest delivery', () => { + expect( + shallow() + ).toMatchSnapshot(); +}); + +it('should render correctly a failed delivery', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); + +it('should display the latest delivery form', () => { + const wrapper = shallow(); + click(wrapper.find('ButtonIcon')); + expect(wrapper.find('LatestDeliveryForm').exists()).toBeTruthy(); +}); diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveriesForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveriesForm-test.tsx.snap index 42cff706441..10fa36144a7 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveriesForm-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveriesForm-test.tsx.snap @@ -53,7 +53,7 @@ exports[`should render correctly 2`] = `
- -
+ } +> + + +`; + +exports[`should render correctly 2`] = ` + + } +> + + +`; diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveryItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveryItem-test.tsx.snap index 350ab5714c6..a39dd9db7b8 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveryItem-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveryItem-test.tsx.snap @@ -1,84 +1,86 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should render correctly 1`] = ` - - } -> -
+

+ webhooks.delivery.response_x.200 +

+

+ webhooks.delivery.duration_x.20ms +

+

-

- webhooks.delivery.response_x.200 -

-

- webhooks.delivery.duration_x.20ms -

-

- webhooks.delivery.payload -

- + + -
-
+ +
`; -exports[`should render correctly 2`] = ` - +

+ webhooks.delivery.response_x.webhooks.delivery.server_unreachable +

+

+ webhooks.delivery.duration_x.20ms +

+

+ webhooks.delivery.payload +

+ + - } -> -
+
+`; + +exports[`should render correctly when no payload 1`] = ` +
+

+ webhooks.delivery.response_x.200 +

+

+ webhooks.delivery.duration_x.20ms +

+

-

- webhooks.delivery.response_x.200 -

-

- webhooks.delivery.duration_x.20ms -

-

- webhooks.delivery.payload -

- - - -
-
+ webhooks.delivery.payload +

+ + `; diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/LatestDeliveryForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/LatestDeliveryForm-test.tsx.snap new file mode 100644 index 00000000000..eff0d0fa8f5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/LatestDeliveryForm-test.tsx.snap @@ -0,0 +1,80 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` + +
+

+ webhooks.latest_delivery_for_x.foo +

+
+ +
+ +
+
+`; + +exports[`should render correctly 2`] = ` + +
+

+ webhooks.latest_delivery_for_x.foo +

+
+ +
+ +
+
+`; diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap index 99338c1907f..08780ac6201 100644 --- a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap @@ -9,14 +9,12 @@ exports[`should render correctly 1`] = ` http://webhook.target - @@ -30,13 +28,6 @@ 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", } @@ -45,35 +36,3 @@ exports[`should render correctly 1`] = ` `; - -exports[`should render correctly the latest delivery 1`] = ` - - webhooks.last_execution.none - -`; - -exports[`should render correctly the latest delivery 2`] = ` - - - - - - -`; - -exports[`should render correctly the latest delivery 3`] = ` - - - - - - -`; diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItemLatestDelivery-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItemLatestDelivery-test.tsx.snap new file mode 100644 index 00000000000..43db29698f9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItemLatestDelivery-test.tsx.snap @@ -0,0 +1,49 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly a failed delivery 1`] = ` + + + + + + + + + +`; + +exports[`should render correctly a success delivery 1`] = ` + + + + + + + + + +`; + +exports[`should render correctly when no latest delivery 1`] = ` + + webhooks.last_execution.none + +`; diff --git a/server/sonar-web/src/main/js/components/controls/ListFooter.tsx b/server/sonar-web/src/main/js/components/controls/ListFooter.tsx index 3d438c9cf0e..d17a5a3385e 100644 --- a/server/sonar-web/src/main/js/components/controls/ListFooter.tsx +++ b/server/sonar-web/src/main/js/components/controls/ListFooter.tsx @@ -24,6 +24,7 @@ import { formatMeasure } from '../../helpers/measures'; interface Props { count: number; + className?: string; loadMore?: () => void; ready?: boolean; total: number; @@ -44,9 +45,11 @@ export default function ListFooter({ ready = true, ...props }: Props) { {translate('show_more')} ); - const className = classNames('spacer-top note text-center', { - 'new-loading': !ready - }); + const className = classNames( + 'spacer-top note text-center', + { 'new-loading': !ready }, + props.className + ); return (