Преглед изворни кода

SONAR-18447 Migrate webhook page tests to RTL

tags/10.2.0.77647
7PH пре 11 месеци
родитељ
комит
88df0979c9
24 измењених фајлова са 398 додато и 1453 уклоњено
  1. 6
    4
      server/sonar-web/src/main/js/apps/webhooks/components/PageActions.tsx
  2. 6
    2
      server/sonar-web/src/main/js/apps/webhooks/components/WebhookItemLatestDelivery.tsx
  3. 385
    0
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-it.tsx
  4. 0
    176
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx
  5. 0
    145
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/CreateWebhookForm-it.tsx
  6. 0
    77
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveriesForm-test.tsx
  7. 0
    72
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryAccordion-test.tsx
  8. 0
    61
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/LatestDeliveryForm-test.tsx
  9. 0
    51
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageActions-test.tsx
  10. 0
    32
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageHeader-test.tsx
  11. 0
    85
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookActions-test.tsx
  12. 0
    57
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx
  13. 0
    68
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItemLatestDelivery-test.tsx
  14. 0
    46
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhooksList-test.tsx
  15. 0
    79
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/App-test.tsx.snap
  16. 0
    104
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveriesForm-test.tsx.snap
  17. 0
    78
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/LatestDeliveryForm-test.tsx.snap
  18. 0
    30
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageActions-test.tsx.snap
  19. 0
    34
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
  20. 0
    55
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookActions-test.tsx.snap
  21. 0
    85
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap
  22. 0
    49
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItemLatestDelivery-test.tsx.snap
  23. 0
    63
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap
  24. 1
    0
      sonar-core/src/main/resources/org/sonar/l10n/core.properties

+ 6
- 4
server/sonar-web/src/main/js/apps/webhooks/components/PageActions.tsx Прегледај датотеку

@@ -18,8 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { Button } from '../../../components/controls/buttons';
import Tooltip from '../../../components/controls/Tooltip';
import { Button } from '../../../components/controls/buttons';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import CreateWebhookForm from './CreateWebhookForm';

@@ -33,7 +33,7 @@ interface State {
openCreate: boolean;
}

const WEBHOOKS_LIMIT = 10;
export const WEBHOOKS_LIMIT = 10;

export default class PageActions extends React.PureComponent<Props, State> {
mounted = false;
@@ -61,14 +61,16 @@ export default class PageActions extends React.PureComponent<Props, State> {
if (this.props.webhooksCount >= WEBHOOKS_LIMIT) {
return (
<Tooltip overlay={translateWithParameters('webhooks.maximum_reached', WEBHOOKS_LIMIT)}>
<Button className="js-webhook-create disabled">{translate('create')}</Button>
<Button className="it__webhook-create" disabled>
{translate('create')}
</Button>
</Tooltip>
);
}

return (
<>
<Button className="js-webhook-create" onClick={this.handleCreateOpen}>
<Button className="it__webhook-create" onClick={this.handleCreateOpen}>
{translate('create')}
</Button>
{this.state.openCreate && (

+ 6
- 2
server/sonar-web/src/main/js/apps/webhooks/components/WebhookItemLatestDelivery.tsx Прегледај датотеку

@@ -23,7 +23,7 @@ import AlertErrorIcon from '../../../components/icons/AlertErrorIcon';
import AlertSuccessIcon from '../../../components/icons/AlertSuccessIcon';
import BulletListIcon from '../../../components/icons/BulletListIcon';
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
import { translate } from '../../../helpers/l10n';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { WebhookResponse } from '../../../types/webhook';
import LatestDeliveryForm from './LatestDeliveryForm';

@@ -73,7 +73,11 @@ export default class WebhookItemLatestDelivery extends React.PureComponent<Props
)}
<span className="spacer-left display-inline-flex-center">
<DateTimeFormatter date={webhook.latestDelivery.at} />
<ButtonIcon className="button-small little-spacer-left" onClick={this.handleClick}>
<ButtonIcon
aria-label={translateWithParameters('webhooks.last_execution.open_for_x', webhook.name)}
className="button-small little-spacer-left"
onClick={this.handleClick}
>
<BulletListIcon />
</ButtonIcon>
</span>

+ 385
- 0
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-it.tsx Прегледај датотеку

@@ -0,0 +1,385 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { act, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import WebhooksMock from '../../../../api/mocks/WebhooksMock';
import { mockComponent } from '../../../../helpers/mocks/component';
import { mockWebhook } from '../../../../helpers/mocks/webhook';
import { renderComponent } from '../../../../helpers/testReactTestingUtils';
import { byLabelText, byRole, byText } from '../../../../helpers/testSelector';
import { App } from '../App';
import { WEBHOOKS_LIMIT } from '../PageActions';

const webhookService = new WebhooksMock();

beforeEach(() => {
webhookService.reset();
});

describe('app should render correctly', () => {
it('global webhooks', async () => {
const { ui } = getPageObject();
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

expect(ui.webhookTable.get()).toBeInTheDocument();
ui.checkWebhookRow(0, {
name: 'Global webhook 1',
url: 'https://example.com/1',
secret: false,
lastDeliveryDate: 'June 24, 2019',
});
ui.checkWebhookRow(1, {
name: 'Global webhook 2',
url: 'https://example.com/2',
secret: true,
});
});

it('project webhooks', async () => {
const { ui } = getPageObject();
webhookService.reset('project1');
renderWebhooksApp({
component: mockComponent({ key: 'project1' }),
});
await ui.waitForWebhooksLoaded();

expect(ui.webhookTable.get()).toBeInTheDocument();
ui.checkWebhookRow(0, {
name: 'Project 1 webhook 1',
url: 'https://example.com/1',
secret: false,
lastDeliveryDate: 'June 24, 2019',
});
ui.checkWebhookRow(1, {
name: 'Project 1 webhook 2',
url: 'https://example.com/2',
secret: false,
});
});

it('project with no webhook', async () => {
const { ui } = getPageObject();
webhookService.reset('project2');
renderWebhooksApp({
component: mockComponent({ key: 'project2' }),
});
await ui.waitForNoResults();

expect(ui.webhookTable.query()).not.toBeInTheDocument();
});
});

describe('webhook CRUD', () => {
it('should not allow webhook creation when too many', async () => {
const { ui } = getPageObject();
webhookService.addWebhook(
...Array.from({ length: 8 }).map((_, i) => mockWebhook({ key: `newwebhook${i}` }))
);
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

expect(ui.webhookCreateButton.get()).toBeDisabled();
await expect(ui.webhookCreateButton.get()).toHaveATooltipWithContent(
`webhooks.maximum_reached.${WEBHOOKS_LIMIT}`
);
});

// eslint-disable-next-line jest/expect-expect
it('should allow to create a webhook', async () => {
const { ui, user } = getPageObject();
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

await act(async () => {
await user.click(ui.webhookCreateButton.get());
});
await ui.fillUpdateForm('new-webhook');
ui.formShouldNotBeValid();
await ui.fillUpdateForm(undefined, 'https://webhook.example.sonarqube.com');
await ui.submitForm();

ui.checkWebhookRow(2, {
name: 'new-webhook',
url: 'https://webhook.example.sonarqube.com',
secret: false,
});
});

// eslint-disable-next-line jest/expect-expect
it('should allow to update a webhook', async () => {
const { ui } = getPageObject();
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

await ui.clickWebhookRowAction(1, 'Global webhook 2', 'update_verb');
await ui.fillUpdateForm('modified-webhook', 'https://webhook.example.sonarqube.com', 'secret');
await ui.submitForm();

ui.checkWebhookRow(1, {
name: 'modified-webhook',
url: 'https://webhook.example.sonarqube.com',
secret: true,
lastDeliveryDate: 'webhooks.last_execution.none',
});

// Edit again, removing the secret
await ui.clickWebhookRowAction(1, 'modified-webhook', 'update_verb');
await ui.fillUpdateForm(undefined, undefined, '');
await ui.submitForm();

ui.checkWebhookRow(1, {
name: 'modified-webhook',
url: 'https://webhook.example.sonarqube.com',
secret: false,
lastDeliveryDate: 'webhooks.last_execution.none',
});

// Edit once again, not touching the secret
await ui.clickWebhookRowAction(1, 'modified-webhook', 'update_verb');
await ui.fillUpdateForm('modified-webhook2');
await ui.submitForm();

ui.checkWebhookRow(1, {
name: 'modified-webhook',
url: 'https://webhook.example.sonarqube.com',
secret: false,
lastDeliveryDate: 'webhooks.last_execution.none',
});
});

it('should allow to delete a webhook', async () => {
const { ui } = getPageObject();
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

expect(ui.webhookRow.getAll()).toHaveLength(3); // We count the header
await ui.clickWebhookRowAction(0, 'Global webhook 1', 'delete');
await ui.submitForm();
expect(ui.webhookRow.getAll()).toHaveLength(2);
});
});

describe('should properly show deliveries', () => {
it('should render delivery list', async () => {
const { ui } = getPageObject();
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

await act(async () => {
await ui.clickWebhookRowAction(0, 'Global webhook 1', 'webhooks.deliveries.show');
});
ui.checkDeliveryRow(0, {
date: 'June 24, 2019',
status: 'success',
});
ui.checkDeliveryRow(1, {
date: 'June 23, 2019',
status: 'success',
});
ui.checkDeliveryRow(2, {
date: 'June 22, 2019',
status: 'error',
});
ui.checkDeliveryRow(3, {
date: 'June 21, 2019',
status: 'success',
});

await act(async () => {
await ui.toggleDeliveryRow(1);
});
expect(screen.getByText('webhooks.delivery.response_x.200')).toBeInTheDocument();
expect(screen.getByText('webhooks.delivery.duration_x.1s')).toBeInTheDocument();
expect(screen.getByText('{ "id": "global-webhook-1-delivery-0" }')).toBeInTheDocument();

await act(async () => {
await ui.toggleDeliveryRow(1);
await ui.toggleDeliveryRow(2);
});
expect(
screen.getByText('webhooks.delivery.response_x.webhooks.delivery.server_unreachable')
).toBeInTheDocument();
expect(screen.getByText('webhooks.delivery.duration_x.1s')).toBeInTheDocument();
expect(screen.getByText('{ "id": "global-webhook-1-delivery-1" }')).toBeInTheDocument();
});

it('should render delivery modal', async () => {
const { ui } = getPageObject();
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

await ui.clickWebhookLatestDelivery(0, 'Global webhook 1');
expect(screen.getByText('webhooks.delivery.response_x.200')).toBeInTheDocument();
expect(screen.getByText('webhooks.delivery.duration_x.20ms')).toBeInTheDocument();
expect(screen.getByText('{ "id": "global-delivery1" }')).toBeInTheDocument();
});

it('should handle pagination', async () => {
const { ui, user } = getPageObject();
renderWebhooksApp();
await ui.waitForWebhooksLoaded();

await ui.clickWebhookRowAction(0, 'Global webhook 1', 'webhooks.deliveries.show');
expect(screen.getByText('x_of_y_shown.10.16')).toBeInTheDocument();

await act(async () => {
await user.click(screen.getByRole('button', { name: 'show_more' }));
});
expect(screen.getByText('x_of_y_shown.16.16')).toBeInTheDocument();
});
});

function renderWebhooksApp(overrides: Partial<App['props']> = {}) {
return renderComponent(<App {...overrides} />);
}

function getPageObject() {
const user = userEvent.setup();

const selectors = {
webhookCreateButton: byRole('button', { name: 'create' }),
webhookTable: byRole('table'),
webhookRow: byRole('row'),
noWebhook: byText('webhooks.no_result'),
formDialog: byRole('dialog'),
formNameInput: byRole('textbox', { name: 'webhooks.name field_required' }),
formUrlInput: byRole('textbox', { name: 'webhooks.url field_required' }),
formSecretInput: byLabelText('webhooks.secret'),
formSecretInputMaskButton: byRole('button', { name: 'webhooks.secret.field_mask.link' }),
formUpdateButton: byRole('button', { name: 'update_verb' }),
};

const ui = {
...selectors,

// General
waitForWebhooksLoaded: async () => {
expect(await selectors.webhookTable.find()).toBeInTheDocument();
},
waitForNoResults: async () => {
expect(await selectors.noWebhook.find()).toBeInTheDocument();
},

// Row-related
getWebhookRow: (index: number) => {
return selectors.webhookRow.getAll()[index + 1];
},
clickWebhookRowAction: async (rowIndex: number, webhookName: string, actionName: string) => {
const row = ui.getWebhookRow(rowIndex);
await act(async () => {
await user.click(
within(row).getByRole('button', { name: `webhooks.show_actions.${webhookName}` })
);
await user.click(within(row).getByRole('button', { name: actionName }));
});
},
clickWebhookLatestDelivery: async (rowIndex: number, webhookName: string) => {
const row = ui.getWebhookRow(rowIndex);
await act(async () => {
await user.click(
within(row).getByRole('button', {
name: `webhooks.last_execution.open_for_x.${webhookName}`,
})
);
});
},
checkWebhookRow: (
index: number,
expected: { name: string; url: string; secret: boolean; lastDeliveryDate?: string }
) => {
const row = ui.getWebhookRow(index);
const [name, url, secret, lastDelivery] = within(row).getAllByRole('cell');
expect(name).toHaveTextContent(expected.name);
expect(url).toHaveTextContent(expected.url);
expect(secret).toHaveTextContent(expected.secret ? 'yes' : 'no');
expect(lastDelivery).toHaveTextContent(
expected.lastDeliveryDate
? new RegExp(expected.lastDeliveryDate)
: 'webhooks.last_execution.none'
);
},

// Creation/Update form
fillUpdateForm: async (name?: string, url?: string, secret?: string) => {
await act(async () => {
if (name !== undefined) {
await user.clear(selectors.formNameInput.get());
await user.type(selectors.formNameInput.get(), name);
}
if (url !== undefined) {
await user.clear(selectors.formUrlInput.get());
await user.type(selectors.formUrlInput.get(), url);
}
if (secret !== undefined) {
// Do we have to update secret
const secretMaskButton = selectors.formSecretInputMaskButton.get();
if (secretMaskButton) {
await user.click(secretMaskButton);
}
await user.clear(selectors.formSecretInput.get());
if (secret) {
await user.type(selectors.formSecretInput.get(), secret);
}
}
});
},
getFormSubmitButton: () => {
const form = selectors.formDialog.get();
return within(form)
.getAllByRole('button')
.filter((b: HTMLButtonElement) => b.type === 'submit')[0];
},
formShouldNotBeValid: () => {
expect(ui.getFormSubmitButton()).toBeDisabled();
},
submitForm: async () => {
await act(async () => {
const submitBtn = ui.getFormSubmitButton();
await user.click(submitBtn);
});
await waitFor(() => expect(selectors.formDialog.query()).not.toBeInTheDocument());
},

// Deliveries
getDeliveryRow: (index: number) => {
const dialog = selectors.formDialog.get();
const rows = within(dialog).getAllByRole('listitem');
return rows[index];
},
checkDeliveryRow: (index: number, expected: { date: string; status: 'success' | 'error' }) => {
const row = ui.getDeliveryRow(index);
const date = within(row).getByRole('button');
expect(date).toHaveTextContent(new RegExp(expected.date));
const status = within(row).getByLabelText(expected.status);
expect(status).toBeInTheDocument();
},
toggleDeliveryRow: async (index: number) => {
const row = ui.getDeliveryRow(index);
await user.click(within(row).getByRole('button'));
},
};

return {
ui,
user,
};
}

+ 0
- 176
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/App-test.tsx Прегледај датотеку

@@ -1,176 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import {
createWebhook,
deleteWebhook,
searchWebhooks,
updateWebhook,
} from '../../../../api/webhooks';
import { mockComponent } from '../../../../helpers/mocks/component';
import { App } from '../App';

jest.mock('../../../../api/webhooks', () => ({
createWebhook: jest.fn(() =>
Promise.resolve({ webhook: { key: '3', name: 'baz', url: 'http://baz', hasSecret: false } })
),
deleteWebhook: jest.fn(() => Promise.resolve()),
searchWebhooks: jest.fn(() =>
Promise.resolve({
webhooks: [
{ key: '1', name: 'foo', url: 'http://foo', hasSecret: false },
{ key: '2', name: 'bar', url: 'http://bar', hasSecret: false },
],
})
),
updateWebhook: jest.fn(() => Promise.resolve()),
}));

const component = mockComponent({ key: 'bar', qualifier: 'TRK' });

beforeEach(() => {
(createWebhook as jest.Mock<any>).mockClear();
(deleteWebhook as jest.Mock<any>).mockClear();
(searchWebhooks as jest.Mock<any>).mockClear();
(updateWebhook as jest.Mock<any>).mockClear();
});

it('should be in loading status', () => {
expect(shallow(<App />)).toMatchSnapshot();
});

it('should fetch webhooks and display them', async () => {
const wrapper = shallow(<App />);
expect(wrapper.state('loading')).toBe(true);

await new Promise(setImmediate);
expect(searchWebhooks).toHaveBeenCalledWith({});

wrapper.update();
expect(wrapper).toMatchSnapshot();
});

describe('should correctly fetch webhooks when', () => {
it('on global scope', async () => {
shallow(<App />);

await new Promise(setImmediate);
expect(searchWebhooks).toHaveBeenCalledWith({ projects: undefined });
});

it('on project scope', async () => {
shallow(<App component={component} />);

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

it('should correctly handle webhook creation', async () => {
const webhook = { name: 'baz', url: 'http://baz' };
const wrapper = shallow(<App />);
(wrapper.instance() as App).handleCreate({ ...webhook });
expect(createWebhook).toHaveBeenLastCalledWith({
...webhook,
project: undefined,
});

await new Promise(setImmediate);
wrapper.update();
expect(wrapper.state('webhooks')).toEqual([
{ key: '1', name: 'foo', url: 'http://foo', hasSecret: false },
{ key: '2', name: 'bar', url: 'http://bar', hasSecret: false },
{ key: '3', name: 'baz', url: 'http://baz', hasSecret: false },
]);
});

it('should correctly handle webhook deletion', async () => {
const wrapper = shallow(<App />);
(wrapper.instance() as App).handleDelete('2');
expect(deleteWebhook).toHaveBeenLastCalledWith({ webhook: '2' });

await new Promise(setImmediate);
wrapper.update();
expect(wrapper.state('webhooks')).toEqual([
{ key: '1', name: 'foo', url: 'http://foo', hasSecret: false },
]);
});

it('should correctly handle webhook update', async () => {
const newValues = { webhook: '1', name: 'Cfoo', url: 'http://cfoo', secret: undefined };
const wrapper = shallow(<App />);
(wrapper.instance() as App).handleUpdate(newValues);
expect(updateWebhook).toHaveBeenLastCalledWith(newValues);

await new Promise(setImmediate);
wrapper.update();
expect(wrapper.state('webhooks')).toEqual([
{ key: '1', name: 'Cfoo', url: 'http://cfoo', hasSecret: false },
{ key: '2', name: 'bar', url: 'http://bar', hasSecret: false },
]);
});

it('should correctly handle webhook secret update', async () => {
const newValuesWithSecret = { webhook: '2', name: 'bar', url: 'http://bar', secret: 'secret' };
const newValuesWithoutSecret = {
webhook: '2',
name: 'bar',
url: 'http://bar',
secret: undefined,
};
const newValuesWithEmptySecret = { webhook: '2', name: 'bar', url: 'http://bar', secret: '' };
const wrapper = shallow(<App />);

// With secret
(wrapper.instance() as App).handleUpdate(newValuesWithSecret);
expect(updateWebhook).toHaveBeenLastCalledWith(newValuesWithSecret);

await new Promise(setImmediate);
wrapper.update();
expect(wrapper.state('webhooks')).toEqual([
{ key: '1', name: 'foo', url: 'http://foo', hasSecret: false },
{ key: '2', name: 'bar', url: 'http://bar', hasSecret: true },
]);

// Without secret
(wrapper.instance() as App).handleUpdate(newValuesWithoutSecret);
expect(updateWebhook).toHaveBeenLastCalledWith(newValuesWithoutSecret);

await new Promise(setImmediate);
wrapper.update();
expect(wrapper.state('webhooks')).toEqual([
{ key: '1', name: 'foo', url: 'http://foo', hasSecret: false },
{ key: '2', name: 'bar', url: 'http://bar', hasSecret: true },
]);

// With empty secret
(wrapper.instance() as App).handleUpdate(newValuesWithEmptySecret);
expect(updateWebhook).toHaveBeenLastCalledWith(newValuesWithEmptySecret);

await new Promise(setImmediate);
wrapper.update();
expect(wrapper.state('webhooks')).toEqual([
{ key: '1', name: 'foo', url: 'http://foo', hasSecret: false },
{ key: '2', name: 'bar', url: 'http://bar', hasSecret: false },
]);
});

+ 0
- 145
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/CreateWebhookForm-it.tsx Прегледај датотеку

@@ -1,145 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 userEvent from '@testing-library/user-event';
import * as React from 'react';
import { renderComponent } from '../../../../helpers/testReactTestingUtils';
import { byLabelText, byRole } from '../../../../helpers/testSelector';
import CreateWebhookForm from '../CreateWebhookForm';

const ui = {
nameInput: byRole('textbox', { name: 'webhooks.name field_required' }),
urlInput: byRole('textbox', { name: 'webhooks.url field_required' }),
secretInput: byLabelText('webhooks.secret'),
secretInputMaskButton: byRole('button', { name: 'webhooks.secret.field_mask.link' }),
createButton: byRole('button', { name: 'create' }),
updateButton: byRole('button', { name: 'update_verb' }),
};

describe('Webhook form', () => {
it('should correctly submit creation form', async () => {
const user = userEvent.setup();
const webhook = {
name: 'foo',
url: 'http://bar',
secret: '',
};
const onDone = jest.fn();

renderCreateWebhookForm({ onDone });

expect(ui.nameInput.get()).toHaveValue('');
expect(ui.urlInput.get()).toHaveValue('');
expect(ui.secretInput.get()).toHaveValue('');
expect(ui.createButton.get()).toBeDisabled();

await user.type(ui.nameInput.get(), webhook.name);
await user.type(ui.urlInput.get(), webhook.url);
expect(ui.createButton.get()).toBeEnabled();

await user.click(ui.createButton.get());
expect(onDone).toHaveBeenCalledWith(webhook);
});

it('should correctly submit update form', async () => {
const user = userEvent.setup();
const webhook = {
hasSecret: false,
key: 'test-webhook-key',
name: 'foo',
url: 'http://bar',
};
const nameExtension = 'bar';
const url = 'http://bar';
const onDone = jest.fn();

renderCreateWebhookForm({ onDone, webhook });

expect(ui.nameInput.get()).toHaveValue(webhook.name);
expect(ui.urlInput.get()).toHaveValue(webhook.url);
expect(ui.secretInput.query()).not.toBeInTheDocument();
expect(ui.secretInputMaskButton.get()).toBeInTheDocument();
expect(ui.updateButton.get()).toBeDisabled();

await user.type(ui.nameInput.get(), nameExtension);
await user.clear(ui.urlInput.get());
await user.type(ui.urlInput.get(), url);
expect(ui.updateButton.get()).toBeEnabled();

await user.click(ui.updateButton.get());
expect(onDone).toHaveBeenCalledWith({
name: `${webhook.name}${nameExtension}`,
url,
secret: undefined,
});
});

it('should correctly submit update form with empty secret', async () => {
const user = userEvent.setup();
const webhook = {
hasSecret: false,
key: 'test-webhook-key',
name: 'foo',
url: 'http://bar',
};
const onDone = jest.fn();

renderCreateWebhookForm({ onDone, webhook });

await user.click(ui.secretInputMaskButton.get());
expect(ui.updateButton.get()).toBeEnabled();

await user.click(ui.updateButton.get());
expect(onDone).toHaveBeenCalledWith({
name: webhook.name,
url: webhook.url,
secret: '',
});
});

it('should correctly submit update form with updated secret', async () => {
const user = userEvent.setup();
const webhook = {
hasSecret: false,
key: 'test-webhook-key',
name: 'foo',
url: 'http://bar',
};
const secret = 'test-webhook-secret';
const onDone = jest.fn();

renderCreateWebhookForm({ onDone, webhook });

await user.click(ui.secretInputMaskButton.get());
await user.type(ui.secretInput.get(), secret);

await user.click(ui.updateButton.get());
expect(onDone).toHaveBeenCalledWith({
name: webhook.name,
url: webhook.url,
secret,
});
});
});

function renderCreateWebhookForm(props = {}) {
return renderComponent(
<CreateWebhookForm onClose={jest.fn()} onDone={jest.fn(() => Promise.resolve())} {...props} />
);
}

+ 0
- 77
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveriesForm-test.tsx Прегледај датотеку

@@ -1,77 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import { searchDeliveries } from '../../../../api/webhooks';
import DeliveriesForm from '../DeliveriesForm';

jest.mock('../../../../api/webhooks', () => ({
searchDeliveries: jest.fn(() =>
Promise.resolve({
deliveries: [
{
at: '12.02.2018',
durationMs: 20,
httpStatus: 200,
id: '2',
success: true,
},
{
at: '11.02.2018',
durationMs: 122,
httpStatus: 500,
id: '1',
success: false,
},
],
paging: {
pageIndex: 1,
pageSize: 10,
total: 15,
},
})
),
}));

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

beforeEach(() => {
(searchDeliveries as jest.Mock<any>).mockClear();
});

it('should render correctly', async () => {
const wrapper = getWrapper();
expect(wrapper).toMatchSnapshot();

await new Promise(setImmediate);
expect(searchDeliveries as jest.Mock<any>).toHaveBeenLastCalledWith({
webhook: webhook.key,
ps: 10,
});
wrapper.update();
expect(wrapper).toMatchSnapshot();

wrapper.find('ListFooter').prop<Function>('loadMore')();
expect(searchDeliveries).toHaveBeenLastCalledWith({ webhook: webhook.key, p: 2, ps: 10 });
});

function getWrapper(props = {}) {
return shallow(<DeliveriesForm onClose={jest.fn()} webhook={webhook} {...props} />);
}

+ 0
- 72
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/DeliveryAccordion-test.tsx Прегледај датотеку

@@ -1,72 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import * as React from 'react';
import { getDelivery } from '../../../../api/webhooks';
import { mockWebhookDelivery } from '../../../../helpers/mocks/webhook';
import { HttpStatus } from '../../../../helpers/request';
import { renderComponent } from '../../../../helpers/testReactTestingUtils';
import DeliveryAccordion from '../DeliveryAccordion';

jest.mock('../../../../api/webhooks', () => ({
getDelivery: jest.fn().mockResolvedValue({
delivery: { payload: '{ "message": "This was successful" }' },
}),
}));

beforeEach(jest.clearAllMocks);

it('should render correctly for successful payloads', async () => {
const user = userEvent.setup();
renderDeliveryAccordion();
expect(screen.getByLabelText('success')).toBeInTheDocument();

await user.click(screen.getByRole('button'));
expect(screen.getByText(`webhooks.delivery.response_x.${HttpStatus.Ok}`)).toBeInTheDocument();
expect(screen.getByText('webhooks.delivery.duration_x.20ms')).toBeInTheDocument();
expect(screen.getByText('webhooks.delivery.payload')).toBeInTheDocument();

const codeSnippet = await screen.findByText('{ "message": "This was successful" }');
expect(codeSnippet).toBeInTheDocument();
});

it('should render correctly for errored payloads', async () => {
const user = userEvent.setup();
(getDelivery as jest.Mock).mockResolvedValueOnce({
delivery: { payload: '503 Service Unavailable' },
});
renderDeliveryAccordion({
delivery: mockWebhookDelivery({ httpStatus: undefined, success: false }),
});
expect(screen.getByLabelText('error')).toBeInTheDocument();

await user.click(screen.getByRole('button'));
expect(
screen.getByText('webhooks.delivery.response_x.webhooks.delivery.server_unreachable')
).toBeInTheDocument();

const codeSnippet = await screen.findByText('503 Service Unavailable');
expect(codeSnippet).toBeInTheDocument();
});

function renderDeliveryAccordion(props: Partial<DeliveryAccordion['props']> = {}) {
return renderComponent(<DeliveryAccordion delivery={mockWebhookDelivery()} {...props} />);
}

+ 0
- 61
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/LatestDeliveryForm-test.tsx Прегледај датотеку

@@ -1,61 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import { getDelivery } from '../../../../api/webhooks';
import LatestDeliveryForm from '../LatestDeliveryForm';

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', hasSecret: false };

beforeEach(() => {
(getDelivery as jest.Mock<any>).mockClear();
});

it('should render correctly', async () => {
const wrapper = getWrapper();
expect(wrapper).toMatchSnapshot();

await new Promise(setImmediate);
expect(getDelivery).toHaveBeenLastCalledWith({ deliveryId: delivery.id });
wrapper.update();
expect(wrapper).toMatchSnapshot();
});

function getWrapper(props = {}) {
return shallow(
<LatestDeliveryForm delivery={delivery} onClose={jest.fn()} webhook={webhook} {...props} />
);
}

+ 0
- 51
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageActions-test.tsx Прегледај датотеку

@@ -1,51 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import { click } from '../../../../helpers/testUtils';
import PageActions from '../PageActions';

it('should render correctly', () => {
expect(getWrapper()).toMatchSnapshot();
});

it('should not render', () => {
expect(getWrapper({ loading: true }).type()).toBeNull();
});

it('should not allow to create a new webhook', () => {
expect(getWrapper({ webhooksCount: 10 })).toMatchSnapshot();
});

it('should display the create form', () => {
const onCreate = jest.fn();
const wrapper = getWrapper({ onCreate });
click(wrapper.find('.js-webhook-create'));
expect(wrapper.find('CreateWebhookForm').exists()).toBe(true);
wrapper.find('CreateWebhookForm').prop<Function>('onDone')({
name: 'foo',
url: 'http://foo.bar',
});
expect(onCreate).toHaveBeenLastCalledWith({ name: 'foo', url: 'http://foo.bar' });
});

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

+ 0
- 32
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/PageHeader-test.tsx Прегледај датотеку

@@ -1,32 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import PageHeader from '../PageHeader';

it('should render correctly', () => {
expect(
shallow(
<PageHeader loading>
<div />
</PageHeader>
)
).toMatchSnapshot();
});

+ 0
- 85
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookActions-test.tsx Прегледај датотеку

@@ -1,85 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import { click } from '../../../../helpers/testUtils';
import WebhookActions from '../WebhookActions';

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

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

it('should render correctly', () => {
expect(getWrapper()).toMatchSnapshot();
});

it('should display the update webhook form', () => {
const onUpdate = jest.fn(() => Promise.resolve());
const wrapper = getWrapper({ onUpdate });
click(wrapper.find('.js-webhook-update'));
expect(wrapper.find('CreateWebhookForm').exists()).toBe(true);
wrapper.find('CreateWebhookForm').prop<Function>('onDone')({
name: webhook.name,
url: webhook.url,
});
expect(onUpdate).toHaveBeenLastCalledWith({
webhook: webhook.key,
name: webhook.name,
url: webhook.url,
});
});

it('should display the delete webhook form', () => {
const onDelete = jest.fn(() => Promise.resolve());
const wrapper = getWrapper({ onDelete });
click(wrapper.find('.js-webhook-delete'));
expect(wrapper.find('DeleteWebhookForm').exists()).toBe(true);
wrapper.find('DeleteWebhookForm').prop<Function>('onSubmit')();
expect(onDelete).toHaveBeenLastCalledWith(webhook.key);
});

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

function getWrapper(props = {}) {
return shallow(
<WebhookActions
onDelete={jest.fn(() => Promise.resolve())}
onUpdate={jest.fn(() => Promise.resolve())}
webhook={webhook}
{...props}
/>
);
}

+ 0
- 57
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItem-test.tsx Прегледај датотеку

@@ -1,57 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import WebhookItem from '../WebhookItem';

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

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

it('should render correctly', () => {
expect(
shallow(
<WebhookItem
onDelete={jest.fn(() => Promise.resolve())}
onUpdate={jest.fn(() => Promise.resolve())}
webhook={webhookWithoutSecret}
/>
)
).toMatchSnapshot();
expect(
shallow(
<WebhookItem
onDelete={jest.fn(() => Promise.resolve())}
onUpdate={jest.fn(() => Promise.resolve())}
webhook={webhookWithSecret}
/>
)
).toMatchSnapshot();
});

+ 0
- 68
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhookItemLatestDelivery-test.tsx Прегледај датотеку

@@ -1,68 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import { click } from '../../../../helpers/testUtils';
import WebhookItemLatestDelivery from '../WebhookItemLatestDelivery';

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',
hasSecret: false,
latestDelivery,
};

it('should render correctly a success delivery', () => {
expect(shallow(<WebhookItemLatestDelivery webhook={webhook} />)).toMatchSnapshot();
});

it('should render correctly when no latest delivery', () => {
expect(
shallow(<WebhookItemLatestDelivery webhook={{ ...webhook, latestDelivery: undefined }} />)
).toMatchSnapshot();
});

it('should render correctly a failed delivery', () => {
expect(
shallow(
<WebhookItemLatestDelivery
webhook={{
...webhook,
latestDelivery: { ...latestDelivery, httpStatus: 500, success: false },
}}
/>
)
).toMatchSnapshot();
});

it('should display the latest delivery form', () => {
const wrapper = shallow(<WebhookItemLatestDelivery webhook={webhook} />);
click(wrapper.find('ButtonIcon'));
expect(wrapper.find('LatestDeliveryForm').exists()).toBe(true);
});

+ 0
- 46
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/WebhooksList-test.tsx Прегледај датотеку

@@ -1,46 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2023 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 { shallow } from 'enzyme';
import * as React from 'react';
import WebhooksList from '../WebhooksList';

const webhooks = [
{ key: '1', name: 'my webhook', url: 'http://webhook.target', hasSecret: false },
{ key: '2', name: 'jenkins webhook', url: 'http://jenkins.target', hasSecret: false },
];

it('should correctly render empty webhook list', () => {
expect(getWrapper({ webhooks: [] })).toMatchSnapshot();
});

it('should correctly render the webhooks', () => {
expect(getWrapper()).toMatchSnapshot();
});

function getWrapper(props = {}) {
return shallow(
<WebhooksList
onDelete={jest.fn(() => Promise.resolve())}
onUpdate={jest.fn(() => Promise.resolve())}
webhooks={webhooks}
{...props}
/>
);
}

+ 0
- 79
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/App-test.tsx.snap Прегледај датотеку

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

exports[`should be in loading status 1`] = `
<Fragment>
<Suggestions
suggestions="webhooks"
/>
<Helmet
defer={false}
encodeSpecialCharacters={true}
prioritizeSeoTags={false}
title="webhooks.page"
/>
<div
className="page page-limited"
>
<PageHeader
loading={true}
>
<PageActions
loading={true}
onCreate={[Function]}
webhooksCount={0}
/>
</PageHeader>
</div>
</Fragment>
`;

exports[`should fetch webhooks and display them 1`] = `
<Fragment>
<Suggestions
suggestions="webhooks"
/>
<Helmet
defer={false}
encodeSpecialCharacters={true}
prioritizeSeoTags={false}
title="webhooks.page"
/>
<div
className="page page-limited"
>
<PageHeader
loading={false}
>
<PageActions
loading={false}
onCreate={[Function]}
webhooksCount={2}
/>
</PageHeader>
<div
className="boxed-group boxed-group-inner"
>
<WebhooksList
onDelete={[Function]}
onUpdate={[Function]}
webhooks={
[
{
"hasSecret": false,
"key": "1",
"name": "foo",
"url": "http://foo",
},
{
"hasSecret": false,
"key": "2",
"name": "bar",
"url": "http://bar",
},
]
}
/>
</div>
</div>
</Fragment>
`;

+ 0
- 104
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/DeliveriesForm-test.tsx.snap Прегледај датотеку

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

exports[`should render correctly 1`] = `
<Modal
contentLabel="webhooks.deliveries_for_x.foo"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
webhooks.deliveries_for_x.foo
</h2>
</header>
<div
className="modal-body modal-container"
>
<div
className="text-center"
>
<DeferredSpinner
loading={true}
/>
</div>
</div>
<footer
className="modal-foot"
>
<ResetButtonLink
className="js-modal-close"
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
`;

exports[`should render correctly 2`] = `
<Modal
contentLabel="webhooks.deliveries_for_x.foo"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
webhooks.deliveries_for_x.foo
</h2>
</header>
<div
className="modal-body modal-container"
>
<DeliveryAccordion
delivery={
{
"at": "12.02.2018",
"durationMs": 20,
"httpStatus": 200,
"id": "2",
"success": true,
}
}
key="2"
/>
<DeliveryAccordion
delivery={
{
"at": "11.02.2018",
"durationMs": 122,
"httpStatus": 500,
"id": "1",
"success": false,
}
}
key="1"
/>
<div
className="text-center"
>
<DeferredSpinner
loading={false}
/>
</div>
<ListFooter
className="little-spacer-bottom"
count={2}
loadMore={[Function]}
ready={true}
total={15}
/>
</div>
<footer
className="modal-foot"
>
<ResetButtonLink
className="js-modal-close"
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
`;

+ 0
- 78
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/LatestDeliveryForm-test.tsx.snap Прегледај датотеку

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

exports[`should render correctly 1`] = `
<Modal
contentLabel="webhooks.latest_delivery_for_x.foo"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
webhooks.latest_delivery_for_x.foo
</h2>
</header>
<DeliveryItem
className="modal-body modal-container"
delivery={
{
"at": "12.02.2018",
"durationMs": 20,
"httpStatus": 200,
"id": "2",
"success": true,
}
}
loading={true}
/>
<footer
className="modal-foot"
>
<ResetButtonLink
className="js-modal-close"
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
`;

exports[`should render correctly 2`] = `
<Modal
contentLabel="webhooks.latest_delivery_for_x.foo"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
webhooks.latest_delivery_for_x.foo
</h2>
</header>
<DeliveryItem
className="modal-body modal-container"
delivery={
{
"at": "12.02.2018",
"durationMs": 20,
"httpStatus": 200,
"id": "2",
"success": true,
}
}
loading={false}
payload="{ "success": true }"
/>
<footer
className="modal-foot"
>
<ResetButtonLink
className="js-modal-close"
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
`;

+ 0
- 30
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageActions-test.tsx.snap Прегледај датотеку

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

exports[`should not allow to create a new webhook 1`] = `
<div
className="page-actions"
>
<Tooltip
overlay="webhooks.maximum_reached.10"
>
<Button
className="js-webhook-create disabled"
>
create
</Button>
</Tooltip>
</div>
`;

exports[`should render correctly 1`] = `
<div
className="page-actions"
>
<Button
className="js-webhook-create"
onClick={[Function]}
>
create
</Button>
</div>
`;

+ 0
- 34
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap Прегледај датотеку

@@ -1,34 +0,0 @@
// 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"
/>
<div />
<p
className="page-description"
>
<FormattedMessage
defaultMessage="webhooks.description"
id="webhooks.description"
values={
{
"url": <DocLink
to="/project-administration/webhooks/"
>
webhooks.documentation_link
</DocLink>,
}
}
/>
</p>
</header>
`;

+ 0
- 55
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookActions-test.tsx.snap Прегледај датотеку

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

exports[`should display the deliveries form 1`] = `
<Fragment>
<ActionsDropdown
className="big-spacer-left"
label="webhooks.show_actions.foo"
>
<ActionsDropdownItem
className="js-webhook-update"
onClick={[Function]}
>
update_verb
</ActionsDropdownItem>
<ActionsDropdownItem
className="js-webhook-deliveries"
onClick={[Function]}
>
webhooks.deliveries.show
</ActionsDropdownItem>
<ActionsDropdownDivider />
<ActionsDropdownItem
className="js-webhook-delete"
destructive={true}
onClick={[Function]}
>
delete
</ActionsDropdownItem>
</ActionsDropdown>
</Fragment>
`;

exports[`should render correctly 1`] = `
<Fragment>
<ActionsDropdown
className="big-spacer-left"
label="webhooks.show_actions.foo"
>
<ActionsDropdownItem
className="js-webhook-update"
onClick={[Function]}
>
update_verb
</ActionsDropdownItem>
<ActionsDropdownDivider />
<ActionsDropdownItem
className="js-webhook-delete"
destructive={true}
onClick={[Function]}
>
delete
</ActionsDropdownItem>
</ActionsDropdown>
</Fragment>
`;

+ 0
- 85
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItem-test.tsx.snap Прегледај датотеку

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

exports[`should render correctly 1`] = `
<tr>
<td>
my webhook
</td>
<td>
http://webhook.target
</td>
<td>
no
</td>
<td>
<WebhookItemLatestDelivery
webhook={
{
"hasSecret": false,
"key": "1",
"name": "my webhook",
"url": "http://webhook.target",
}
}
/>
</td>
<td
className="sw-text-right"
>
<WebhookActions
onDelete={[MockFunction]}
onUpdate={[MockFunction]}
webhook={
{
"hasSecret": false,
"key": "1",
"name": "my webhook",
"url": "http://webhook.target",
}
}
/>
</td>
</tr>
`;

exports[`should render correctly 2`] = `
<tr>
<td>
my webhook
</td>
<td>
http://webhook.target
</td>
<td>
yes
</td>
<td>
<WebhookItemLatestDelivery
webhook={
{
"hasSecret": true,
"key": "1",
"name": "my webhook",
"url": "http://webhook.target",
}
}
/>
</td>
<td
className="sw-text-right"
>
<WebhookActions
onDelete={[MockFunction]}
onUpdate={[MockFunction]}
webhook={
{
"hasSecret": true,
"key": "1",
"name": "my webhook",
"url": "http://webhook.target",
}
}
/>
</td>
</tr>
`;

+ 0
- 49
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhookItemLatestDelivery-test.tsx.snap Прегледај датотеку

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

exports[`should render correctly a failed delivery 1`] = `
<Fragment>
<AlertErrorIcon
className="text-text-top"
/>
<span
className="spacer-left display-inline-flex-center"
>
<DateTimeFormatter
date="12.02.2018"
/>
<ButtonIcon
className="button-small little-spacer-left"
onClick={[Function]}
>
<BulletListIcon />
</ButtonIcon>
</span>
</Fragment>
`;

exports[`should render correctly a success delivery 1`] = `
<Fragment>
<AlertSuccessIcon
className="text-text-top"
/>
<span
className="spacer-left display-inline-flex-center"
>
<DateTimeFormatter
date="12.02.2018"
/>
<ButtonIcon
className="button-small little-spacer-left"
onClick={[Function]}
>
<BulletListIcon />
</ButtonIcon>
</span>
</Fragment>
`;

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

+ 0
- 63
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/WebhooksList-test.tsx.snap Прегледај датотеку

@@ -1,63 +0,0 @@
// 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>
<th>
webhooks.secret_header
</th>
<th>
webhooks.last_execution
</th>
<th
className="sw-text-right"
>
actions
</th>
</tr>
</thead>
<tbody>
<WebhookItem
key="2"
onDelete={[MockFunction]}
onUpdate={[MockFunction]}
webhook={
{
"hasSecret": false,
"key": "2",
"name": "jenkins webhook",
"url": "http://jenkins.target",
}
}
/>
<WebhookItem
key="1"
onDelete={[MockFunction]}
onUpdate={[MockFunction]}
webhook={
{
"hasSecret": false,
"key": "1",
"name": "my webhook",
"url": "http://webhook.target",
}
}
/>
</tbody>
</table>
`;

+ 1
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties Прегледај датотеку

@@ -4791,6 +4791,7 @@ webhooks.delivery.server_unreachable=Server Unreachable
webhooks.documentation_link=Webhooks documentation
webhooks.last_execution=Last delivery
webhooks.last_execution.none=Never
webhooks.last_execution.open_for_x=Open last delivery of {0}
webhooks.latest_delivery_for_x=Last delivery of {0}
webhooks.maximum_reached=You reached your maximum number of {0} webhooks. You can still update or delete an existing one.
webhooks.name=Name

Loading…
Откажи
Сачувај