From 3c5c062c8bf27f5ed93c72871d9d9ddcf4c0c548 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Wed, 31 Jan 2018 11:23:12 +0100 Subject: [PATCH] SONAR-10344 Create the webhooks console page * SONAR-10348 Create the webhooks console page * SONAR-10349 Add webhook console at global admin scope * SONAR-10349 Add webhook console at project scope * SONAR-10349 Add webhook console at organization scope --- server/sonar-web/src/main/js/api/webhooks.ts | 43 ++++++++++ ...Container.js => ProjectAdminContainer.tsx} | 34 ++++---- .../nav/component/ComponentNavMenu.tsx | 16 ++++ .../ComponentNavMenu-test.tsx.snap | 57 +++++++++++++ .../components/nav/settings/SettingsNav.tsx | 5 ++ .../__snapshots__/SettingsNav-test.tsx.snap | 8 ++ .../src/main/js/app/utils/startReactApp.js | 3 + .../OrganizationNavigationAdministration.tsx | 5 ++ ...tionNavigationAdministration-test.tsx.snap | 10 +++ .../src/main/js/apps/organizations/routes.ts | 4 +- .../main/js/apps/webhooks/components/App.tsx | 84 +++++++++++++++++++ .../apps/webhooks/components/PageHeader.tsx | 52 ++++++++++++ .../apps/webhooks/components/WebhookItem.tsx | 34 ++++++++ .../apps/webhooks/components/WebhooksList.tsx | 58 +++++++++++++ .../components/__tests__/App-test.tsx | 83 ++++++++++++++++++ .../components/__tests__/PageHeader-test.tsx | 26 ++++++ .../components/__tests__/WebhookItem-test.tsx | 28 +++++++ .../__tests__/WebhooksList-test.tsx | 35 ++++++++ .../__tests__/__snapshots__/App-test.tsx.snap | 38 +++++++++ .../__snapshots__/PageHeader-test.tsx.snap | 35 ++++++++ .../__snapshots__/WebhookItem-test.tsx.snap | 12 +++ .../__snapshots__/WebhooksList-test.tsx.snap | 46 ++++++++++ .../src/main/js/apps/webhooks/routes.ts | 32 +++++++ .../resources/org/sonar/l10n/core.properties | 13 +++ 24 files changed, 744 insertions(+), 17 deletions(-) create mode 100644 server/sonar-web/src/main/js/api/webhooks.ts rename server/sonar-web/src/main/js/app/components/{ProjectAdminContainer.js => ProjectAdminContainer.tsx} (82%) create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/App.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/WebhooksList.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageHeader-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhooksList-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/App-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/apps/webhooks/routes.ts diff --git a/server/sonar-web/src/main/js/api/webhooks.ts b/server/sonar-web/src/main/js/api/webhooks.ts new file mode 100644 index 00000000000..fa526855e02 --- /dev/null +++ b/server/sonar-web/src/main/js/api/webhooks.ts @@ -0,0 +1,43 @@ +/* + * 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 { getJSON } from '../helpers/request'; +import throwGlobalError from '../app/utils/throwGlobalError'; + +export interface Delivery { + id: string; + at: string; + success: boolean; + httpStatus: number; + durationMs: number; +} + +export interface Webhook { + key: string; + name: string; + url: string; + latestDelivery?: Delivery; +} + +export function searchWebhooks(data: { + organization: string | undefined; + project?: string; +}): Promise<{ webhooks: Webhook[] }> { + return getJSON('/api/webhooks/search', data).catch(throwGlobalError); +} diff --git a/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js b/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.tsx similarity index 82% rename from server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js rename to server/sonar-web/src/main/js/app/components/ProjectAdminContainer.tsx index 2c70fb9401d..612f4bb043f 100644 --- a/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js +++ b/server/sonar-web/src/main/js/app/components/ProjectAdminContainer.tsx @@ -17,20 +17,22 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import React from 'react'; +import * as React from 'react'; import handleRequiredAuthorization from '../utils/handleRequiredAuthorization'; +import { Component, Branch } from '../types'; -export default class ProjectAdminContainer extends React.PureComponent { - /*:: - props: { - component: { - configuration?: { - showSettings: boolean - } - } - }; - */ +interface Props { + children: JSX.Element; + branch?: Branch; + branches: Branch[]; + component: Component; + isInProgress?: boolean; + isPending?: boolean; + onBranchesChange: () => void; + onComponentChange: (changes: {}) => void; +} +export default class ProjectAdminContainer extends React.PureComponent { componentDidMount() { this.checkPermissions(); } @@ -39,17 +41,17 @@ export default class ProjectAdminContainer extends React.PureComponent { this.checkPermissions(); } - isProjectAdmin() { - const { configuration } = this.props.component; - return configuration != null && configuration.showSettings; - } - checkPermissions() { if (!this.isProjectAdmin()) { handleRequiredAuthorization(); } } + isProjectAdmin() { + const { configuration } = this.props.component; + return configuration != null && configuration.showSettings; + } + render() { if (!this.isProjectAdmin()) { return null; diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.tsx b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.tsx index 564a54ea318..bb56f7751a8 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.tsx @@ -243,6 +243,7 @@ export default class ComponentNavMenu extends React.PureComponent { this.renderPermissionsLink(), this.renderBackgroundTasksLink(), this.renderUpdateKeyLink(), + this.renderWebhooksLink(), ...this.renderAdminExtensions(), this.renderDeletionLink() ]; @@ -394,6 +395,21 @@ export default class ComponentNavMenu extends React.PureComponent { ); } + renderWebhooksLink() { + if (!this.getConfiguration().showSettings || !this.isProject()) { + return null; + } + return ( +
  • + + {translate('webhooks.page')} + +
  • + ); + } + renderDeletionLink() { const { qualifier } = this.props.component; diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMenu-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMenu-test.tsx.snap index 56558732e74..592b1d44eee 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMenu-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMenu-test.tsx.snap @@ -150,6 +150,25 @@ exports[`should work for all qualifiers 1`] = ` project_branches.page +
  • + + webhooks.page + +
  • @@ -1060,6 +1079,25 @@ exports[`should work with extensions 1`] = ` project_branches.page
  • +
  • + + webhooks.page + +
  • @@ -1292,6 +1330,25 @@ exports[`should work with multiple extensions 1`] = ` project_branches.page
  • +
  • + + webhooks.page + +
  • diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx index 32433c78d15..7f50c588689 100644 --- a/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx @@ -117,6 +117,11 @@ export default class SettingsNav extends React.PureComponent { {translate('custom_metrics.page')}
  • +
  • + + {translate('webhooks.page')} + +
  • {extensionsWithoutSupport.map(this.renderExtension)} diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap index 64822b179f6..a80573d7d9d 100644 --- a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap @@ -55,6 +55,14 @@ exports[`should work with extensions 1`] = ` custom_metrics.page +
  • + + webhooks.page + +
  • diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.js b/server/sonar-web/src/main/js/app/utils/startReactApp.js index c6af220da94..98968f52f68 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.js +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.js @@ -74,6 +74,7 @@ import settingsRoutes from '../../apps/settings/routes'; import systemRoutes from '../../apps/system/routes'; import usersRoutes from '../../apps/users/routes'; import webAPIRoutes from '../../apps/web-api/routes'; +import webhooksRoutes from '../../apps/webhooks/routes'; import { maintenanceRoutes, setupRoutes } from '../../apps/maintenance/routes'; import { globalPermissionsRoutes, projectPermissionsRoutes } from '../../apps/permissions/routes'; @@ -212,6 +213,7 @@ const startReactApp = () => { + {projectAdminRoutes} @@ -232,6 +234,7 @@ const startReactApp = () => { + diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationAdministration.tsx b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationAdministration.tsx index 0446e83c50d..cc2b9631ee8 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationAdministration.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationAdministration.tsx @@ -92,6 +92,11 @@ export default function OrganizationNavigationAdministration({ location, organiz {translate('projects_management')}
  • +
  • + + {translate('webhooks.page')} + +
  • {translate('edit')} diff --git a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigationAdministration-test.tsx.snap b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigationAdministration-test.tsx.snap index 713261b2290..c7764bf1c8b 100644 --- a/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigationAdministration-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigationAdministration-test.tsx.snap @@ -58,6 +58,16 @@ exports[`renders 1`] = ` projects_management
  • +
  • + + webhooks.page + +
  • { + mounted: boolean = false; + state: State = { loading: true, webhooks: [] }; + + componentDidMount() { + this.mounted = true; + this.fetchWebhooks(); + } + + componentWillUnmount() { + this.mounted = false; + } + + fetchWebhooks = ({ organization, component } = this.props) => { + this.setState({ loading: true }); + searchWebhooks({ + organization: organization && organization.key, + project: component && component.key + }).then( + ({ webhooks }) => { + if (this.mounted) { + this.setState({ loading: false, webhooks }); + } + }, + () => { + if (this.mounted) { + this.setState({ loading: false }); + } + } + ); + }; + + render() { + const { loading, webhooks } = this.state; + return ( +
    + + + {!loading && ( +
    + +
    + )} +
    + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx new file mode 100644 index 00000000000..229b835e5e9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx @@ -0,0 +1,52 @@ +/* + * 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 { FormattedMessage } from 'react-intl'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + loading: boolean; +} + +export default function PageHeader({ loading }: Props) { + return ( +
    +

    {translate('webhooks.page')}

    + {loading && } + +

    + + {translate('webhooks.documentation_link')} + + ) + }} + /> +

    +
    + ); +} 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 new file mode 100644 index 00000000000..1be6a9da181 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx @@ -0,0 +1,34 @@ +/* + * 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 { Webhook } from '../../../api/webhooks'; + +interface Props { + webhook: Webhook; +} + +export default function WebhookItem({ webhook }: Props) { + return ( + + {webhook.name} + {webhook.url} + + ); +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/WebhooksList.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/WebhooksList.tsx new file mode 100644 index 00000000000..61689e75561 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/WebhooksList.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 WebhookItem from './WebhookItem'; +import { Webhook } from '../../../api/webhooks'; +import { translate } from '../../../helpers/l10n'; + +interface Props { + webhooks: Webhook[]; +} + +export default class WebhooksList extends React.PureComponent { + renderHeader = () => ( + + + {translate('name')} + {translate('webhooks.url')} + + + ); + + renderNoWebhooks = () => ( + + {translate('webhooks.no_result')} + + ); + + render() { + const { webhooks } = this.props; + return ( + + {this.renderHeader()} + + {webhooks.length > 0 + ? webhooks.map(webhook => ) + : this.renderNoWebhooks()} + +
    + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx new file mode 100644 index 00000000000..085def84f20 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx @@ -0,0 +1,83 @@ +/* + * 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 App from '../App'; +import { searchWebhooks } from '../../../../api/webhooks'; +import { Visibility } from '../../../../app/types'; + +jest.mock('../../../../api/webhooks', () => ({ + searchWebhooks: jest.fn(() => Promise.resolve({ webhooks: [] })) +})); + +const organization = { key: 'foo', name: 'Foo', projectVisibility: Visibility.Private }; +const component = { key: 'bar', organization: 'foo', qualifier: 'TRK' }; + +beforeEach(() => { + (searchWebhooks as jest.Mock).mockClear(); +}); + +it('should be in loading status', () => { + expect(shallow()).toMatchSnapshot(); +}); + +it('should fetch webhooks and display them', async () => { + const wrapper = shallow(); + expect(wrapper.state('loading')).toBeTruthy(); + + await new Promise(setImmediate); + expect(searchWebhooks).toHaveBeenCalledWith({ organization: organization.key }); + + wrapper.update(); + expect(wrapper).toMatchSnapshot(); +}); + +describe('should correctly fetch webhooks when', () => { + it('on global scope', async () => { + shallow(); + + await new Promise(setImmediate); + expect(searchWebhooks).toHaveBeenCalledWith({ organization: undefined }); + }); + + it('on project scope', async () => { + shallow(); + + await new Promise(setImmediate); + expect(searchWebhooks).toHaveBeenCalledWith({ project: component.key }); + }); + + it('on organization scope', async () => { + shallow(); + + await new Promise(setImmediate); + expect(searchWebhooks).toHaveBeenCalledWith({ organization: organization.key }); + }); + + it('on project scope within an organization', async () => { + shallow(); + + await new Promise(setImmediate); + expect(searchWebhooks).toHaveBeenCalledWith({ + organization: organization.key, + project: component.key + }); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageHeader-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageHeader-test.tsx new file mode 100644 index 00000000000..148d1570cd4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageHeader-test.tsx @@ -0,0 +1,26 @@ +/* + * 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 PageHeader from '../PageHeader'; + +it('should render correctly', () => { + expect(shallow()).toMatchSnapshot(); +}); 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 new file mode 100644 index 00000000000..ab0a1a5d0e4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx @@ -0,0 +1,28 @@ +/* + * 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 WebhookItem from '../WebhookItem'; + +const webhook = { key: '1', name: 'my webhook', url: 'http://webhook.target' }; + +it('should render correctly', () => { + expect(shallow()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhooksList-test.tsx b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhooksList-test.tsx new file mode 100644 index 00000000000..e0337cc8f5c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhooksList-test.tsx @@ -0,0 +1,35 @@ +/* + * 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 WebhooksList from '../WebhooksList'; + +const webhooks = [ + { key: '1', name: 'my webhook', url: 'http://webhook.target' }, + { key: '2', name: 'jenkins webhook', url: 'http://jenkins.target' } +]; + +it('should correctly render empty webhook list', () => { + expect(shallow()).toMatchSnapshot(); +}); + +it('should correctly render the webhooks', () => { + expect(shallow()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/App-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/App-test.tsx.snap new file mode 100644 index 00000000000..717e2e76bb0 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/App-test.tsx.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should be in loading status 1`] = ` +
    + + +
    +`; + +exports[`should fetch webhooks and display them 1`] = ` +
    + + +
    + +
    +
    +`; diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap new file mode 100644 index 00000000000..e40da7ba2d3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` +
    +

    + webhooks.page +

    + +

    + + webhooks.documentation_link + , + } + } + /> +

    +
    +`; 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 new file mode 100644 index 00000000000..b6968c76bed --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render correctly 1`] = ` + + + my webhook + + + http://webhook.target + + +`; diff --git a/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap new file mode 100644 index 00000000000..01bcb34685a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should correctly render empty webhook list 1`] = ` +

    + webhooks.no_result +

    +`; + +exports[`should correctly render the webhooks 1`] = ` + + + + + + + + + + + +
    + name + + webhooks.url +
    +`; diff --git a/server/sonar-web/src/main/js/apps/webhooks/routes.ts b/server/sonar-web/src/main/js/apps/webhooks/routes.ts new file mode 100644 index 00000000000..fbd6fae2b97 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/webhooks/routes.ts @@ -0,0 +1,32 @@ +/* + * 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 { RouterState, RouteComponent } from 'react-router'; + +const routes = [ + { + indexRoute: { + getComponent(_: RouterState, callback: (err: any, component: RouteComponent) => any) { + import('./components/App').then(i => callback(null, i.default)); + } + } + } +]; + +export default routes; diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 96ad44def59..93542c18764 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2805,3 +2805,16 @@ favorite.current.APP=This application is marked as favorite. favorite.current.FIL=This file is marked as favorite. favorite.current.CLA=This file is marked as favorite. favorite.current.UTS=This test file is marked as favorite. + + + +#------------------------------------------------------------------------------ +# +# WEBHOOKS +# +#------------------------------------------------------------------------------ +webhooks.page=Webhooks +webhooks.description=Webhooks are used to notify external services when a project analysis is done. An HTTP POST request including a JSON payload is sent to each of the provided URLs. Learn more in the {url}. +webhooks.documentation_link=Webhooks documentation +webhooks.no_result=No webhook defined. +webhooks.url=URL -- 2.39.5