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

[7.x] [Ingest pipelines] Upload indexed document to test a pipeline (#77939) #78577

Merged
merged 1 commit into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ const appServices = {
api: apiService,
notifications: notificationServiceMock.createSetupContract(),
history,
urlGenerators: {
getUrlGenerator: jest.fn().mockReturnValue({
createUrl: jest.fn(),
}),
},
};

export const setupEnvironment = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,20 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => {
]);
};

const setFetchDocumentsResponse = (response?: HttpResponse, error?: any) => {
const status = error ? error.status || 400 : 200;
const body = error ? JSON.stringify(error.body) : JSON.stringify(response);

server.respondWith('GET', '/api/ingest_pipelines/documents/:index/:id', [
status,
{ 'Content-Type': 'application/json' },
body,
]);
};

return {
setSimulatePipelineResponse,
setFetchDocumentsResponse,
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ const appServices = {
notifications: notificationServiceMock.createSetupContract(),
history,
uiSettings: {},
urlGenerators: {
getUrlGenerator: jest.fn().mockReturnValue({
createUrl: jest.fn(),
}),
},
};

const testBedSetup = registerTestBed<TestSubject>(
Expand Down Expand Up @@ -180,6 +185,20 @@ const createActions = (testBed: TestBed<TestSubject>) => {
});
component.update();
},

async toggleDocumentsAccordion() {
await act(async () => {
find('addDocumentsAccordion').simulate('click');
});
component.update();
},

async clickAddDocumentButton() {
await act(async () => {
find('addDocumentButton').simulate('click');
});
component.update();
},
};
};

Expand Down Expand Up @@ -229,4 +248,8 @@ type TestSubject =
| 'configurationTab'
| 'outputTab'
| 'processorOutputTabContent'
| 'addDocumentsAccordion'
| 'addDocumentButton'
| 'addDocumentError'
| 'addDocumentSuccess'
| string;
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,9 @@ describe('Test pipeline', () => {
const { actions, find, exists } = testBed;

const error = {
status: 400,
error: 'Bad Request',
message:
'"[parse_exception] [_source] required property is missing, with { property_name="_source" }"',
status: 500,
error: 'Internal server error',
message: 'Internal server error',
};

httpRequestsMockHelpers.setSimulatePipelineResponse(undefined, { body: error });
Expand All @@ -153,13 +152,90 @@ describe('Test pipeline', () => {
actions.clickAddDocumentsButton();

// Add invalid sample documents array and run the pipeline
actions.addDocumentsJson(JSON.stringify([{}]));
actions.addDocumentsJson(
JSON.stringify([
{
_index: 'test',
_id: '1',
_version: 1,
_seq_no: 0,
_primary_term: 1,
_source: {
name: 'John Doe',
},
},
])
);
await actions.clickRunPipelineButton();

// Verify error rendered
expect(exists('pipelineExecutionError')).toBe(true);
expect(find('pipelineExecutionError').text()).toContain(error.message);
});

describe('Add indexed documents', () => {
test('should successfully add an indexed document', async () => {
const { actions, form, exists } = testBed;

const { _index: index, _id: documentId } = DOCUMENTS[0];

httpRequestsMockHelpers.setFetchDocumentsResponse(DOCUMENTS[0]);

// Open flyout
actions.clickAddDocumentsButton();

// Open documents accordion, click run without required fields, and verify error messages
await actions.toggleDocumentsAccordion();
await actions.clickAddDocumentButton();
expect(form.getErrorsMessages()).toEqual([
'An index name is required.',
'A document ID is required.',
]);

// Add required fields, and click run
form.setInputValue('indexField.input', index);
form.setInputValue('idField.input', documentId);
await actions.clickAddDocumentButton();

// Verify request
const latestRequest = server.requests[server.requests.length - 1];
expect(latestRequest.status).toEqual(200);
expect(latestRequest.url).toEqual(`/api/ingest_pipelines/documents/${index}/${documentId}`);
// Verify success callout
expect(exists('addDocumentSuccess')).toBe(true);
});

test('should surface API errors from the request', async () => {
const { actions, form, exists, find } = testBed;

const nonExistentDoc = {
index: 'foo',
id: '1',
};

const error = {
status: 404,
error: 'Not found',
message: '[index_not_found_exception] no such index',
};

httpRequestsMockHelpers.setFetchDocumentsResponse(undefined, { body: error });

// Open flyout
actions.clickAddDocumentsButton();

// Open documents accordion, add required fields, and click run
await actions.toggleDocumentsAccordion();
form.setInputValue('indexField.input', nonExistentDoc.index);
form.setInputValue('idField.input', nonExistentDoc.id);
await actions.clickAddDocumentButton();

// Verify error rendered
expect(exists('addDocumentError')).toBe(true);
expect(exists('addDocumentSuccess')).toBe(false);
expect(find('addDocumentError').text()).toContain(error.message);
});
});
});

describe('Processors', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useTestPipelineContext } from '../../context';
import { serialize } from '../../serialize';
import { DeserializeResult } from '../../deserialize';
import { Document } from '../../types';
import { useIsMounted } from '../../use_is_mounted';
import { TestPipelineFlyout as ViewComponent } from './test_pipeline_flyout';

import { TestPipelineFlyoutTab } from './test_pipeline_flyout_tabs';
Expand All @@ -34,6 +35,7 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
processors,
}) => {
const { services } = useKibana();
const isMounted = useIsMounted();

const {
testPipelineData,
Expand Down Expand Up @@ -74,6 +76,10 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
pipeline: { ...serializedProcessors },
});

if (!isMounted.current) {
return { isSuccessful: false };
}

setIsRunningTest(false);

if (error) {
Expand Down Expand Up @@ -123,6 +129,7 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
return { isSuccessful: true };
},
[
isMounted,
processors,
services.api,
services.notifications.toasts,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
EuiCallOut,
} from '@elastic/eui';

import { Form, FormHook } from '../../../../../shared_imports';
import { FormHook } from '../../../../../shared_imports';
import { Document } from '../../types';

import { Tabs, TestPipelineFlyoutTab, OutputTab, DocumentsTab } from './test_pipeline_flyout_tabs';
Expand Down Expand Up @@ -71,19 +71,11 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
} else {
// default to "Documents" tab
tabContent = (
<Form
<DocumentsTab
form={form}
data-test-subj="testPipelineForm"
isInvalid={form.isSubmitted && !form.isValid}
onSubmit={validateAndTestPipeline}
error={form.getErrors()}
>
<DocumentsTab
validateAndTestPipeline={validateAndTestPipeline}
isRunningTest={isRunningTest}
isSubmitButtonDisabled={form.isSubmitted && !form.isValid}
/>
</Form>
validateAndTestPipeline={validateAndTestPipeline}
isRunningTest={isRunningTest}
/>
);
}

Expand Down
Loading