--- /dev/null
+/*
+ * 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);
+}
+++ /dev/null
-/*
- * 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 React from 'react';
-import handleRequiredAuthorization from '../utils/handleRequiredAuthorization';
-
-export default class ProjectAdminContainer extends React.PureComponent {
- /*::
- props: {
- component: {
- configuration?: {
- showSettings: boolean
- }
- }
- };
- */
-
- componentDidMount() {
- this.checkPermissions();
- }
-
- componentDidUpdate() {
- this.checkPermissions();
- }
-
- isProjectAdmin() {
- const { configuration } = this.props.component;
- return configuration != null && configuration.showSettings;
- }
-
- checkPermissions() {
- if (!this.isProjectAdmin()) {
- handleRequiredAuthorization();
- }
- }
-
- render() {
- if (!this.isProjectAdmin()) {
- return null;
- }
-
- const { children, ...props } = this.props;
- return React.cloneElement(children, props);
- }
-}
--- /dev/null
+/*
+ * 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 handleRequiredAuthorization from '../utils/handleRequiredAuthorization';
+import { Component, Branch } from '../types';
+
+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<Props> {
+ componentDidMount() {
+ this.checkPermissions();
+ }
+
+ componentDidUpdate() {
+ this.checkPermissions();
+ }
+
+ checkPermissions() {
+ if (!this.isProjectAdmin()) {
+ handleRequiredAuthorization();
+ }
+ }
+
+ isProjectAdmin() {
+ const { configuration } = this.props.component;
+ return configuration != null && configuration.showSettings;
+ }
+
+ render() {
+ if (!this.isProjectAdmin()) {
+ return null;
+ }
+
+ const { children, ...props } = this.props;
+ return React.cloneElement(children, props);
+ }
+}
this.renderPermissionsLink(),
this.renderBackgroundTasksLink(),
this.renderUpdateKeyLink(),
+ this.renderWebhooksLink(),
...this.renderAdminExtensions(),
this.renderDeletionLink()
];
);
}
+ renderWebhooksLink() {
+ if (!this.getConfiguration().showSettings || !this.isProject()) {
+ return null;
+ }
+ return (
+ <li key="webhooks">
+ <Link
+ to={{ pathname: '/project/webhooks', query: { id: this.props.component.key } }}
+ activeClassName="active">
+ {translate('webhooks.page')}
+ </Link>
+ </li>
+ );
+ }
+
renderDeletionLink() {
const { qualifier } = this.props.component;
project_branches.page
</Link>
</li>
+ <li
+ key="webhooks"
+ >
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/webhooks",
+ "query": Object {
+ "id": "foo",
+ },
+ }
+ }
+ >
+ webhooks.page
+ </Link>
+ </li>
<li
key="project_delete"
>
project_branches.page
</Link>
</li>
+ <li
+ key="webhooks"
+ >
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/webhooks",
+ "query": Object {
+ "id": "foo",
+ },
+ }
+ }
+ >
+ webhooks.page
+ </Link>
+ </li>
<li
key="foo"
>
project_branches.page
</Link>
</li>
+ <li
+ key="webhooks"
+ >
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to={
+ Object {
+ "pathname": "/project/webhooks",
+ "query": Object {
+ "id": "foo",
+ },
+ }
+ }
+ >
+ webhooks.page
+ </Link>
+ </li>
<li
key="foo"
>
{translate('custom_metrics.page')}
</IndexLink>
</li>
+ <li>
+ <IndexLink to="/admin/webhooks" activeClassName="active">
+ {translate('webhooks.page')}
+ </IndexLink>
+ </li>
{extensionsWithoutSupport.map(this.renderExtension)}
</ul>
</li>
custom_metrics.page
</IndexLink>
</li>
+ <li>
+ <IndexLink
+ activeClassName="active"
+ to="/admin/webhooks"
+ >
+ webhooks.page
+ </IndexLink>
+ </li>
<li
key="foo"
>
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';
<Route path="project/branches" childRoutes={projectBranchesRoutes} />
<Route path="project/settings" childRoutes={settingsRoutes} />
<Route path="project_roles" childRoutes={projectPermissionsRoutes} />
+ <Route path="project/webhooks" childRoutes={webhooksRoutes} />
</Route>
{projectAdminRoutes}
</Route>
<Route path="system" childRoutes={systemRoutes} />
<Route path="marketplace" childRoutes={marketplaceRoutes} />
<Route path="users" childRoutes={usersRoutes} />
+ <Route path="webhooks" childRoutes={webhooksRoutes} />
</Route>
</Route>
{translate('projects_management')}
</Link>
</li>
+ <li>
+ <Link to={`/organizations/${organization.key}/webhooks`} activeClassName="active">
+ {translate('webhooks.page')}
+ </Link>
+ </li>
<li>
<Link to={`/organizations/${organization.key}/edit`} activeClassName="active">
{translate('edit')}
projects_management
</Link>
</li>
+ <li>
+ <Link
+ activeClassName="active"
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/organizations/foo/webhooks"
+ >
+ webhooks.page
+ </Link>
+ </li>
<li>
<Link
activeClassName="active"
import codingRulesRoutes from '../coding-rules/routes';
import qualityGatesRoutes from '../quality-gates/routes';
import qualityProfilesRoutes from '../quality-profiles/routes';
+import webhooksRoutes from '../webhooks/routes';
import Issues from '../issues/components/AppContainer';
import GroupsApp from '../groups/components/App';
import OrganizationPageExtension from '../../app/components/extensions/OrganizationPageExtension';
{ path: 'groups', component: GroupsApp },
{ path: 'permissions', component: GlobalPermissionsApp },
{ path: 'permission_templates', component: PermissionTemplateApp },
- { path: 'projects_management', component: ProjectManagementApp }
+ { path: 'projects_management', component: ProjectManagementApp },
+ { path: 'webhooks', childRoutes: webhooksRoutes }
]
}
]
--- /dev/null
+/*
+ * 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 { Helmet } from 'react-helmet';
+import PageHeader from './PageHeader';
+import WebhooksList from './WebhooksList';
+import { searchWebhooks, Webhook } from '../../../api/webhooks';
+import { LightComponent, Organization } from '../../../app/types';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ organization: Organization | undefined;
+ component?: LightComponent;
+}
+
+interface State {
+ loading: boolean;
+ webhooks: Webhook[];
+}
+
+export default class App extends React.PureComponent<Props, State> {
+ 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 (
+ <div className="page page-limited">
+ <Helmet title={translate('webhooks.page')} />
+ <PageHeader loading={loading} />
+ {!loading && (
+ <div className="boxed-group boxed-group-inner">
+ <WebhooksList webhooks={webhooks} />
+ </div>
+ )}
+ </div>
+ );
+ }
+}
--- /dev/null
+/*
+ * 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 (
+ <header className="page-header">
+ <h1 className="page-title">{translate('webhooks.page')}</h1>
+ {loading && <i className="spinner" />}
+
+ <p className="page-description">
+ <FormattedMessage
+ defaultMessage={translate('webhooks.description')}
+ id={'webhooks.description'}
+ values={{
+ url: (
+ <a
+ href="https://redirect.sonarsource.com/doc/webhooks.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('webhooks.documentation_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ </header>
+ );
+}
--- /dev/null
+/*
+ * 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 (
+ <tr>
+ <td>{webhook.name}</td>
+ <td>{webhook.url}</td>
+ </tr>
+ );
+}
--- /dev/null
+/*
+ * 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<Props> {
+ renderHeader = () => (
+ <thead>
+ <tr>
+ <th>{translate('name')}</th>
+ <th>{translate('webhooks.url')}</th>
+ </tr>
+ </thead>
+ );
+
+ renderNoWebhooks = () => (
+ <tr>
+ <td>{translate('webhooks.no_result')}</td>
+ </tr>
+ );
+
+ render() {
+ const { webhooks } = this.props;
+ return (
+ <table className="data zebra">
+ {this.renderHeader()}
+ <tbody>
+ {webhooks.length > 0
+ ? webhooks.map(webhook => <WebhookItem key={webhook.key} webhook={webhook} />)
+ : this.renderNoWebhooks()}
+ </tbody>
+ </table>
+ );
+ }
+}
--- /dev/null
+/*
+ * 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<any>).mockClear();
+});
+
+it('should be in loading status', () => {
+ expect(shallow(<App organization={undefined} />)).toMatchSnapshot();
+});
+
+it('should fetch webhooks and display them', async () => {
+ const wrapper = shallow(<App organization={organization} />);
+ 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(<App organization={undefined} />);
+
+ await new Promise(setImmediate);
+ expect(searchWebhooks).toHaveBeenCalledWith({ organization: undefined });
+ });
+
+ it('on project scope', async () => {
+ shallow(<App organization={undefined} component={component} />);
+
+ await new Promise(setImmediate);
+ expect(searchWebhooks).toHaveBeenCalledWith({ project: component.key });
+ });
+
+ it('on organization scope', async () => {
+ shallow(<App organization={organization} component={undefined} />);
+
+ await new Promise(setImmediate);
+ expect(searchWebhooks).toHaveBeenCalledWith({ organization: organization.key });
+ });
+
+ it('on project scope within an organization', async () => {
+ shallow(<App organization={organization} component={component} />);
+
+ await new Promise(setImmediate);
+ expect(searchWebhooks).toHaveBeenCalledWith({
+ organization: organization.key,
+ project: component.key
+ });
+ });
+});
--- /dev/null
+/*
+ * 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(<PageHeader loading={true} />)).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * 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(<WebhookItem webhook={webhook} />)).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * 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(<WebhooksList webhooks={[]} />)).toMatchSnapshot();
+});
+
+it('should correctly render the webhooks', () => {
+ expect(shallow(<WebhooksList webhooks={webhooks} />)).toMatchSnapshot();
+});
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should be in loading status 1`] = `
+<div
+ className="page page-limited"
+>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="webhooks.page"
+ />
+ <PageHeader
+ loading={true}
+ />
+</div>
+`;
+
+exports[`should fetch webhooks and display them 1`] = `
+<div
+ className="page page-limited"
+>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="webhooks.page"
+ />
+ <PageHeader
+ loading={false}
+ />
+ <div
+ className="boxed-group boxed-group-inner"
+ >
+ <WebhooksList
+ webhooks={Array []}
+ />
+ </div>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<header
+ className="page-header"
+>
+ <h1
+ className="page-title"
+ >
+ webhooks.page
+ </h1>
+ <i
+ className="spinner"
+ />
+ <p
+ className="page-description"
+ >
+ <FormattedMessage
+ defaultMessage="webhooks.description"
+ id="webhooks.description"
+ values={
+ Object {
+ "url": <a
+ href="https://redirect.sonarsource.com/doc/webhooks.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ webhooks.documentation_link
+ </a>,
+ }
+ }
+ />
+ </p>
+</header>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<tr>
+ <td>
+ my webhook
+ </td>
+ <td>
+ http://webhook.target
+ </td>
+</tr>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should correctly render empty webhook list 1`] = `
+<p>
+ webhooks.no_result
+</p>
+`;
+
+exports[`should correctly render the webhooks 1`] = `
+<table
+ className="data zebra"
+>
+ <thead>
+ <tr>
+ <th>
+ name
+ </th>
+ <th>
+ webhooks.url
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <WebhookItem
+ key="1"
+ webhook={
+ Object {
+ "key": "1",
+ "name": "my webhook",
+ "url": "http://webhook.target",
+ }
+ }
+ />
+ <WebhookItem
+ key="2"
+ webhook={
+ Object {
+ "key": "2",
+ "name": "jenkins webhook",
+ "url": "http://jenkins.target",
+ }
+ }
+ />
+ </tbody>
+</table>
+`;
--- /dev/null
+/*
+ * 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;
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