Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: unique values only across single service #1413

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
451 changes: 0 additions & 451 deletions ui/src/components/BaseFormView/BaseFormConfigMock.ts

This file was deleted.

4 changes: 2 additions & 2 deletions ui/src/components/BaseFormView/BaseFormView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -609,8 +609,8 @@ class BaseFormView extends PureComponent<BaseFormProps, BaseFormState> {
// validation for unique name
if ([MODE_CREATE, MODE_CLONE].includes(this.props.mode)) {
const isExistingName = Boolean(
Object.values(this.context?.rowData || {}).find((val) =>
Object.keys(val).find((name) => name === this.datadict.name)
Object.keys(this.context?.rowData[this.props.serviceName] || {}).find(
(name) => name === this.datadict.name
)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import { Mode } from '../../../constants/modes';
import { BaseFormProps } from '../../../types/components/BaseFormTypes';
import { Platforms } from '../../../types/globalConfig/pages';
import {
getGlobalConfigMockGroupsForInputPage,
getGlobalConfigMockGroupsForConfigPage,
getGlobalConfigMockGroupsForInputPage,
getGlobalConfigMockModificationToFieldItself,
getGlobalConfigMockModificationToGroupsConfig,
} from '../BaseFormConfigMock';
import { getGlobalConfigMockModificationToFieldItself } from '../tests/configMocks';
} from '../tests/configMocks';
import { invariant } from '../../../util/invariant';

interface BaseFormStoriesProps extends BaseFormProps {
Expand Down
184 changes: 179 additions & 5 deletions ui/src/components/BaseFormView/tests/BaseFormView.test.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import { render, screen } from '@testing-library/react';
import { render, screen, waitFor, within } from '@testing-library/react';
import React from 'react';
import userEvent from '@testing-library/user-event';
import { http, HttpResponse } from 'msw';

import { getGlobalConfigMock } from '../../../mocks/globalConfigMock';
import { getBuildDirPath } from '../../../util/script';
import { setUnifiedConfig } from '../../../util/util';
import { GlobalConfig } from '../../../types/globalConfig/globalConfig';
import mockCustomControlMockForTest from '../../CustomControl/CustomControlMockForTest';
import BaseFormView from '../BaseFormView';
import {
getGlobalConfigMockCustomControl,
getGlobalConfigMockGroupsForInputPage,
getGlobalConfigMockFourInputServices,
getGlobalConfigMockGroupsForConfigPage,
} from '../BaseFormConfigMock';
import mockCustomControlMockForTest from '../../CustomControl/CustomControlMockForTest';
import BaseFormView from '../BaseFormView';
getGlobalConfigMockGroupsForInputPage,
} from './configMocks';
import { MOCK_CONTEXT_STATE_THREE_INPUTS } from './contextMocks';
import { PAGE_INPUT } from '../../../constants/pages';
import { invariant } from '../../../util/invariant';
import TableContext, { TableContextDataTypes } from '../../../context/TableContext';
import { server } from '../../../mocks/server';

const handleFormSubmit = jest.fn();

Expand Down Expand Up @@ -146,3 +154,169 @@ it.each([
verifyDisplayedGroup('2');
verifyDisplayedGroup('3'); // after modifications all groups should be displayed
});

describe('Verify if submiting BaseFormView works', () => {
const renderAndGetFormRef = (
mockConfig: GlobalConfig,
mockContext?: TableContextDataTypes,
serviceName = 'example_input_four'
) => {
setUnifiedConfig(mockConfig);

const formRef = React.createRef<BaseFormView>();

render(
<TableContext.Provider
value={{
...{
rowData: {},
setRowData: () => {},
setSearchText: () => {},
setSearchType: () => {},
pageSize: 10,
setPageSize: () => {},
setCurrentPage: () => {},
currentPage: 0,
searchText: '',
searchType: 'all',
},
...mockContext,
}}
soleksy-splunk marked this conversation as resolved.
Show resolved Hide resolved
>
<BaseFormView
ref={formRef}
page={PAGE_INPUT}
vtsvetkov-splunk marked this conversation as resolved.
Show resolved Hide resolved
stanzaName={STANZA_NAME}
serviceName={serviceName}
mode="create"
handleFormSubmit={handleFormSubmit}
/>
</TableContext.Provider>
);
return formRef;
};

const getEntityTextBox = (entityField: string) => {
const entityWrapper = document.querySelector(`[data-name="${entityField}"]`);
invariant(entityWrapper);
return within(entityWrapper as HTMLElement).getByRole('textbox');
};

it('Correctly pass form data via post', async () => {
const formRef = renderAndGetFormRef(
getGlobalConfigMockFourInputServices(),
MOCK_CONTEXT_STATE_THREE_INPUTS
);

const NAME_INPUT = 'new_unique_test_name';
const INTERVAL_INPUT = '123123123';

const nameInput = getEntityTextBox('name');
await userEvent.type(nameInput, NAME_INPUT);

const intervalInput = getEntityTextBox('interval');
await userEvent.type(intervalInput, INTERVAL_INPUT);

const submitHandler = jest.fn();

server.use(
http.post(
'/servicesNS/nobody/-/demo_addon_for_splunk_example_input_four',
async ({ request }) => {
const formData = await request.formData();
const name = formData.get('name');
const interval = formData.get('interval');
submitHandler(name, interval);
return HttpResponse.json(
soleksy-splunk marked this conversation as resolved.
Show resolved Hide resolved
{
entry: [
{
name,
content: {
interval,
},
},
],
},
{ status: 201 }
);
}
)
);

await formRef.current?.handleSubmit({ preventDefault: () => {} } as React.FormEvent);

// response was success(mocked) and handled
await waitFor(() => expect(handleFormSubmit).toHaveBeenCalledWith(false, true));

// request params(name and interval) had correct values
await waitFor(() => expect(submitHandler).toHaveBeenCalledWith(NAME_INPUT, INTERVAL_INPUT));
});

it('should throw error as name already used', async () => {
const formRef = renderAndGetFormRef(
getGlobalConfigMockFourInputServices(),
MOCK_CONTEXT_STATE_THREE_INPUTS
);

const NAME_INPUT = 'test';
const INTERVAL_INPUT = '123123123';

const nameInput = getEntityTextBox('name');
await userEvent.type(nameInput, NAME_INPUT);

const intervalInput = getEntityTextBox('interval');
await userEvent.type(intervalInput, INTERVAL_INPUT);

await formRef.current?.handleSubmit({ preventDefault: () => {} } as React.FormEvent);

const errorMessage = screen.getByText(`Name ${NAME_INPUT} is already in use`);
expect(errorMessage).toBeInTheDocument();
});

it('Correctly allow same name for different service', async () => {
const formRef = renderAndGetFormRef(
getGlobalConfigMockFourInputServices(),
MOCK_CONTEXT_STATE_THREE_INPUTS,
'example_input_two'
);

const NAME_INPUT = 'test'; // already existing as data in service example_input_one and example_input_four
const INTERVAL_INPUT = '123123123';

const nameInput = getEntityTextBox('name');
await userEvent.type(nameInput, NAME_INPUT);

const intervalInput = getEntityTextBox('interval');
await userEvent.type(intervalInput, INTERVAL_INPUT);

server.use(
http.post(
'/servicesNS/nobody/-/demo_addon_for_splunk_example_input_two',
async ({ request }) => {
const formData = await request.formData();
const name = formData.get('name');
const interval = formData.get('interval');
return HttpResponse.json(
{
entry: [
{
name,
content: {
interval,
},
},
],
},
{ status: 201 }
);
}
)
);

await formRef.current?.handleSubmit({ preventDefault: () => {} } as React.FormEvent);

// response was success(mocked) and handled
await waitFor(() => expect(handleFormSubmit).toHaveBeenCalledWith(false, true));
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { render, screen, within } from '@testing-library/react';
import React from 'react';

import { setUnifiedConfig } from '../../util/util';
import BaseFormView from './BaseFormView';
import { getGlobalConfigMockModificationToGroupsConfig } from './BaseFormConfigMock';
import { setUnifiedConfig } from '../../../util/util';
import BaseFormView from '../BaseFormView';
import { getGlobalConfigMockModificationToGroupsConfig } from './configMocks';

const handleFormSubmit = jest.fn();

Expand Down
Loading
Loading