mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
182 lines
5.3 KiB
TypeScript
182 lines
5.3 KiB
TypeScript
import styled from '@emotion/styled';
|
|
import {SentryAppFixture} from 'sentry-fixture/sentryApp';
|
|
import {SentryAppInstallationFixture} from 'sentry-fixture/sentryAppInstallation';
|
|
|
|
import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
|
|
|
|
import {makeCloseButton} from 'sentry/components/globalModal/components';
|
|
import SentryAppRuleModal from 'sentry/views/alerts/rules/issue/sentryAppRuleModal';
|
|
import type {
|
|
FieldFromSchema,
|
|
SchemaFormConfig,
|
|
} from 'sentry/views/settings/organizationIntegrations/sentryAppExternalForm';
|
|
|
|
describe('SentryAppRuleModal', function () {
|
|
const modalElements = {
|
|
Header: p => p.children,
|
|
Body: p => p.children,
|
|
Footer: p => p.children,
|
|
};
|
|
let sentryApp;
|
|
let sentryAppInstallation;
|
|
|
|
beforeEach(function () {
|
|
sentryApp = SentryAppFixture();
|
|
sentryAppInstallation = SentryAppInstallationFixture();
|
|
});
|
|
|
|
const _submit = async () => {
|
|
await userEvent.click(screen.getByText('Save Changes'));
|
|
return screen.queryAllByText('Field is required');
|
|
};
|
|
|
|
const submitSuccess = async () => {
|
|
const errors = await _submit();
|
|
expect(errors).toHaveLength(0);
|
|
};
|
|
|
|
const submitErrors = async errorCount => {
|
|
const errors = await _submit();
|
|
expect(errors).toHaveLength(errorCount);
|
|
};
|
|
|
|
const defaultConfig: SchemaFormConfig = {
|
|
uri: '/integration/test/',
|
|
description: '',
|
|
required_fields: [
|
|
{
|
|
type: 'text',
|
|
label: 'Alert Title',
|
|
name: 'title',
|
|
},
|
|
{
|
|
type: 'textarea',
|
|
label: 'Alert Description',
|
|
name: 'description',
|
|
},
|
|
{
|
|
type: 'select',
|
|
label: 'Team Channel',
|
|
name: 'channel',
|
|
choices: [
|
|
['valor', 'valor'],
|
|
['mystic', 'mystic'],
|
|
['instinct', 'instinct'],
|
|
],
|
|
},
|
|
],
|
|
optional_fields: [
|
|
{
|
|
type: 'text',
|
|
label: 'Extra Details',
|
|
name: 'extra',
|
|
},
|
|
{
|
|
type: 'select',
|
|
label: 'Assignee',
|
|
name: 'assignee',
|
|
uri: '/link/assignee/',
|
|
},
|
|
{
|
|
type: 'select',
|
|
label: 'Workspace',
|
|
name: 'workspace',
|
|
uri: '/link/workspace/',
|
|
},
|
|
],
|
|
};
|
|
|
|
const resetValues = {
|
|
settings: [
|
|
{
|
|
name: 'extra',
|
|
value: 'saved details from last edit',
|
|
},
|
|
{
|
|
name: 'assignee',
|
|
value: 'edna-mode',
|
|
label: 'Edna Mode',
|
|
},
|
|
],
|
|
};
|
|
|
|
const createWrapper = (props = {}) => {
|
|
const styledWrapper = styled(c => c.children);
|
|
return render(
|
|
<SentryAppRuleModal
|
|
{...modalElements}
|
|
sentryAppInstallationUuid={sentryAppInstallation.uuid}
|
|
appName={sentryApp.name}
|
|
config={defaultConfig}
|
|
onSubmitSuccess={() => {}}
|
|
resetValues={resetValues}
|
|
closeModal={jest.fn()}
|
|
CloseButton={makeCloseButton(() => {})}
|
|
Body={styledWrapper()}
|
|
Footer={styledWrapper()}
|
|
{...props}
|
|
/>
|
|
);
|
|
};
|
|
|
|
describe('Create UI Alert Rule', function () {
|
|
it('should render the Alert Rule modal with the config fields', function () {
|
|
createWrapper();
|
|
const {required_fields, optional_fields} = defaultConfig;
|
|
const allFields = [...required_fields!, ...optional_fields!];
|
|
|
|
allFields.forEach((field: FieldFromSchema) => {
|
|
if (typeof field.label === 'string') {
|
|
expect(screen.getByText(field.label)).toBeInTheDocument();
|
|
}
|
|
});
|
|
});
|
|
|
|
it('should raise validation errors when "Save Changes" is clicked with invalid data', async function () {
|
|
createWrapper();
|
|
await submitErrors(3);
|
|
});
|
|
|
|
it('should submit when "Save Changes" is clicked with valid data', async function () {
|
|
createWrapper();
|
|
|
|
const titleInput = screen.getByTestId('title');
|
|
await userEvent.type(titleInput, 'some title');
|
|
|
|
const descriptionInput = screen.getByTestId('description');
|
|
await userEvent.type(descriptionInput, 'some description');
|
|
|
|
const channelInput = screen.getAllByText('Type to search')[0];
|
|
await userEvent.type(channelInput, '{keyDown}');
|
|
await userEvent.click(screen.getByText('valor'));
|
|
|
|
// Ensure text fields are persisted on edit
|
|
const savedExtraDetailsInput = screen.getByDisplayValue(
|
|
resetValues.settings[0].value
|
|
);
|
|
expect(savedExtraDetailsInput).toBeInTheDocument();
|
|
// Ensure select fields are persisted with labels on edit
|
|
const savedAssigneeInput = screen.getByText(resetValues.settings[1].label!);
|
|
expect(savedAssigneeInput).toBeInTheDocument();
|
|
|
|
// Ensure async select fields filter correctly
|
|
const workspaceChoices = [
|
|
['WS0', 'Primary Workspace'],
|
|
['WS1', 'Secondary Workspace'],
|
|
];
|
|
const workspaceResponse = MockApiClient.addMockResponse({
|
|
url: `/sentry-app-installations/${sentryAppInstallation.uuid}/external-requests/`,
|
|
body: {choices: workspaceChoices},
|
|
});
|
|
const workspaceInput = screen.getByText('Type to search');
|
|
// Search by value
|
|
await userEvent.type(workspaceInput, workspaceChoices[1][0]);
|
|
await waitFor(() => expect(workspaceResponse).toHaveBeenCalled());
|
|
// Select by label
|
|
await userEvent.click(screen.getByText(workspaceChoices[1][1]));
|
|
|
|
await submitSuccess();
|
|
});
|
|
});
|
|
});
|