Просмотр исходного кода

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
tags/7.5
Grégoire Aubert 6 лет назад
Родитель
Сommit
3c5c062c8b
24 измененных файлов: 744 добавлений и 17 удалений
  1. 43
    0
      server/sonar-web/src/main/js/api/webhooks.ts
  2. 18
    16
      server/sonar-web/src/main/js/app/components/ProjectAdminContainer.tsx
  3. 16
    0
      server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.tsx
  4. 57
    0
      server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavMenu-test.tsx.snap
  5. 5
    0
      server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx
  6. 8
    0
      server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.tsx.snap
  7. 3
    0
      server/sonar-web/src/main/js/app/utils/startReactApp.js
  8. 5
    0
      server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationAdministration.tsx
  9. 10
    0
      server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigationAdministration-test.tsx.snap
  10. 3
    1
      server/sonar-web/src/main/js/apps/organizations/routes.ts
  11. 84
    0
      server/sonar-web/src/main/js/apps/webhooks/components/App.tsx
  12. 52
    0
      server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx
  13. 34
    0
      server/sonar-web/src/main/js/apps/webhooks/components/WebhookItem.tsx
  14. 58
    0
      server/sonar-web/src/main/js/apps/webhooks/components/WebhooksList.tsx
  15. 83
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx
  16. 26
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageHeader-test.tsx
  17. 28
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx
  18. 35
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhooksList-test.tsx
  19. 38
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/App-test.tsx.snap
  20. 35
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
  21. 12
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap
  22. 46
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap
  23. 32
    0
      server/sonar-web/src/main/js/apps/webhooks/routes.ts
  24. 13
    0
      sonar-core/src/main/resources/org/sonar/l10n/core.properties

+ 43
- 0
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);
}

server/sonar-web/src/main/js/app/components/ProjectAdminContainer.js → 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<Props> {
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;

+ 16
- 0
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavMenu.tsx Просмотреть файл

@@ -243,6 +243,7 @@ export default class ComponentNavMenu extends React.PureComponent<Props> {
this.renderPermissionsLink(),
this.renderBackgroundTasksLink(),
this.renderUpdateKeyLink(),
this.renderWebhooksLink(),
...this.renderAdminExtensions(),
this.renderDeletionLink()
];
@@ -394,6 +395,21 @@ export default class ComponentNavMenu extends React.PureComponent<Props> {
);
}

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;


+ 57
- 0
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
</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"
>
@@ -1060,6 +1079,25 @@ exports[`should work with extensions 1`] = `
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"
>
@@ -1292,6 +1330,25 @@ exports[`should work with multiple extensions 1`] = `
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"
>

+ 5
- 0
server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.tsx Просмотреть файл

@@ -117,6 +117,11 @@ export default class SettingsNav extends React.PureComponent<Props> {
{translate('custom_metrics.page')}
</IndexLink>
</li>
<li>
<IndexLink to="/admin/webhooks" activeClassName="active">
{translate('webhooks.page')}
</IndexLink>
</li>
{extensionsWithoutSupport.map(this.renderExtension)}
</ul>
</li>

+ 8
- 0
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
</IndexLink>
</li>
<li>
<IndexLink
activeClassName="active"
to="/admin/webhooks"
>
webhooks.page
</IndexLink>
</li>
<li
key="foo"
>

+ 3
- 0
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 = () => {
<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>
@@ -232,6 +234,7 @@ const startReactApp = () => {
<Route path="system" childRoutes={systemRoutes} />
<Route path="marketplace" childRoutes={marketplaceRoutes} />
<Route path="users" childRoutes={usersRoutes} />
<Route path="webhooks" childRoutes={webhooksRoutes} />
</Route>
</Route>


+ 5
- 0
server/sonar-web/src/main/js/apps/organizations/navigation/OrganizationNavigationAdministration.tsx Просмотреть файл

@@ -92,6 +92,11 @@ export default function OrganizationNavigationAdministration({ location, organiz
{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')}

+ 10
- 0
server/sonar-web/src/main/js/apps/organizations/navigation/__tests__/__snapshots__/OrganizationNavigationAdministration-test.tsx.snap Просмотреть файл

@@ -58,6 +58,16 @@ exports[`renders 1`] = `
projects_management
</Link>
</li>
<li>
<Link
activeClassName="active"
onlyActiveOnIndex={false}
style={Object {}}
to="/organizations/foo/webhooks"
>
webhooks.page
</Link>
</li>
<li>
<Link
activeClassName="active"

+ 3
- 1
server/sonar-web/src/main/js/apps/organizations/routes.ts Просмотреть файл

@@ -31,6 +31,7 @@ import ProjectManagementApp from '../projectsManagement/AppContainer';
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';
@@ -88,7 +89,8 @@ const routes = [
{ 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 }
]
}
]

+ 84
- 0
server/sonar-web/src/main/js/apps/webhooks/components/App.tsx Просмотреть файл

@@ -0,0 +1,84 @@
/*
* 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>
);
}
}

+ 52
- 0
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 (
<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>
);
}

+ 34
- 0
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 (
<tr>
<td>{webhook.name}</td>
<td>{webhook.url}</td>
</tr>
);
}

+ 58
- 0
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<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>
);
}
}

+ 83
- 0
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<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
});
});
});

+ 26
- 0
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(<PageHeader loading={true} />)).toMatchSnapshot();
});

+ 28
- 0
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(<WebhookItem webhook={webhook} />)).toMatchSnapshot();
});

+ 35
- 0
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(<WebhooksList webhooks={[]} />)).toMatchSnapshot();
});

it('should correctly render the webhooks', () => {
expect(shallow(<WebhooksList webhooks={webhooks} />)).toMatchSnapshot();
});

+ 38
- 0
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`] = `
<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>
`;

+ 35
- 0
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`] = `
<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>
`;

+ 12
- 0
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`] = `
<tr>
<td>
my webhook
</td>
<td>
http://webhook.target
</td>
</tr>
`;

+ 46
- 0
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`] = `
<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>
`;

+ 32
- 0
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;

+ 13
- 0
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

Загрузка…
Отмена
Сохранить