Skip to content

Commit 88df93b

Browse files
[Ingest pipelines] Upload indexed document to test a pipeline (#77939)
1 parent a71d069 commit 88df93b

File tree

26 files changed

+783
-103
lines changed

26 files changed

+783
-103
lines changed

x-pack/plugins/ingest_pipelines/__jest__/client_integration/helpers/setup_environment.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ const appServices = {
4444
api: apiService,
4545
notifications: notificationServiceMock.createSetupContract(),
4646
history,
47+
urlGenerators: {
48+
getUrlGenerator: jest.fn().mockReturnValue({
49+
createUrl: jest.fn(),
50+
}),
51+
},
4752
};
4853

4954
export const setupEnvironment = () => {

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/http_requests.helpers.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,20 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => {
2121
]);
2222
};
2323

24+
const setFetchDocumentsResponse = (response?: HttpResponse, error?: any) => {
25+
const status = error ? error.status || 400 : 200;
26+
const body = error ? JSON.stringify(error.body) : JSON.stringify(response);
27+
28+
server.respondWith('GET', '/api/ingest_pipelines/documents/:index/:id', [
29+
status,
30+
{ 'Content-Type': 'application/json' },
31+
body,
32+
]);
33+
};
34+
2435
return {
2536
setSimulatePipelineResponse,
37+
setFetchDocumentsResponse,
2638
};
2739
};
2840

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.helpers.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ const appServices = {
9494
notifications: notificationServiceMock.createSetupContract(),
9595
history,
9696
uiSettings: {},
97+
urlGenerators: {
98+
getUrlGenerator: jest.fn().mockReturnValue({
99+
createUrl: jest.fn(),
100+
}),
101+
},
97102
};
98103

99104
const testBedSetup = registerTestBed<TestSubject>(
@@ -180,6 +185,20 @@ const createActions = (testBed: TestBed<TestSubject>) => {
180185
});
181186
component.update();
182187
},
188+
189+
async toggleDocumentsAccordion() {
190+
await act(async () => {
191+
find('addDocumentsAccordion').simulate('click');
192+
});
193+
component.update();
194+
},
195+
196+
async clickAddDocumentButton() {
197+
await act(async () => {
198+
find('addDocumentButton').simulate('click');
199+
});
200+
component.update();
201+
},
183202
};
184203
};
185204

@@ -229,4 +248,8 @@ type TestSubject =
229248
| 'configurationTab'
230249
| 'outputTab'
231250
| 'processorOutputTabContent'
251+
| 'addDocumentsAccordion'
252+
| 'addDocumentButton'
253+
| 'addDocumentError'
254+
| 'addDocumentSuccess'
232255
| string;

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/__jest__/test_pipeline.test.tsx

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,9 @@ describe('Test pipeline', () => {
141141
const { actions, find, exists } = testBed;
142142

143143
const error = {
144-
status: 400,
145-
error: 'Bad Request',
146-
message:
147-
'"[parse_exception] [_source] required property is missing, with { property_name="_source" }"',
144+
status: 500,
145+
error: 'Internal server error',
146+
message: 'Internal server error',
148147
};
149148

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

155154
// Add invalid sample documents array and run the pipeline
156-
actions.addDocumentsJson(JSON.stringify([{}]));
155+
actions.addDocumentsJson(
156+
JSON.stringify([
157+
{
158+
_index: 'test',
159+
_id: '1',
160+
_version: 1,
161+
_seq_no: 0,
162+
_primary_term: 1,
163+
_source: {
164+
name: 'John Doe',
165+
},
166+
},
167+
])
168+
);
157169
await actions.clickRunPipelineButton();
158170

159171
// Verify error rendered
160172
expect(exists('pipelineExecutionError')).toBe(true);
161173
expect(find('pipelineExecutionError').text()).toContain(error.message);
162174
});
175+
176+
describe('Add indexed documents', () => {
177+
test('should successfully add an indexed document', async () => {
178+
const { actions, form, exists } = testBed;
179+
180+
const { _index: index, _id: documentId } = DOCUMENTS[0];
181+
182+
httpRequestsMockHelpers.setFetchDocumentsResponse(DOCUMENTS[0]);
183+
184+
// Open flyout
185+
actions.clickAddDocumentsButton();
186+
187+
// Open documents accordion, click run without required fields, and verify error messages
188+
await actions.toggleDocumentsAccordion();
189+
await actions.clickAddDocumentButton();
190+
expect(form.getErrorsMessages()).toEqual([
191+
'An index name is required.',
192+
'A document ID is required.',
193+
]);
194+
195+
// Add required fields, and click run
196+
form.setInputValue('indexField.input', index);
197+
form.setInputValue('idField.input', documentId);
198+
await actions.clickAddDocumentButton();
199+
200+
// Verify request
201+
const latestRequest = server.requests[server.requests.length - 1];
202+
expect(latestRequest.status).toEqual(200);
203+
expect(latestRequest.url).toEqual(`/api/ingest_pipelines/documents/${index}/${documentId}`);
204+
// Verify success callout
205+
expect(exists('addDocumentSuccess')).toBe(true);
206+
});
207+
208+
test('should surface API errors from the request', async () => {
209+
const { actions, form, exists, find } = testBed;
210+
211+
const nonExistentDoc = {
212+
index: 'foo',
213+
id: '1',
214+
};
215+
216+
const error = {
217+
status: 404,
218+
error: 'Not found',
219+
message: '[index_not_found_exception] no such index',
220+
};
221+
222+
httpRequestsMockHelpers.setFetchDocumentsResponse(undefined, { body: error });
223+
224+
// Open flyout
225+
actions.clickAddDocumentsButton();
226+
227+
// Open documents accordion, add required fields, and click run
228+
await actions.toggleDocumentsAccordion();
229+
form.setInputValue('indexField.input', nonExistentDoc.index);
230+
form.setInputValue('idField.input', nonExistentDoc.id);
231+
await actions.clickAddDocumentButton();
232+
233+
// Verify error rendered
234+
expect(exists('addDocumentError')).toBe(true);
235+
expect(exists('addDocumentSuccess')).toBe(false);
236+
expect(find('addDocumentError').text()).toContain(error.message);
237+
});
238+
});
163239
});
164240

165241
describe('Processors', () => {

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.container.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { useTestPipelineContext } from '../../context';
1212
import { serialize } from '../../serialize';
1313
import { DeserializeResult } from '../../deserialize';
1414
import { Document } from '../../types';
15+
import { useIsMounted } from '../../use_is_mounted';
1516
import { TestPipelineFlyout as ViewComponent } from './test_pipeline_flyout';
1617

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

3840
const {
3941
testPipelineData,
@@ -74,6 +76,10 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
7476
pipeline: { ...serializedProcessors },
7577
});
7678

79+
if (!isMounted.current) {
80+
return { isSuccessful: false };
81+
}
82+
7783
setIsRunningTest(false);
7884

7985
if (error) {
@@ -123,6 +129,7 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
123129
return { isSuccessful: true };
124130
},
125131
[
132+
isMounted,
126133
processors,
127134
services.api,
128135
services.notifications.toasts,

x-pack/plugins/ingest_pipelines/public/application/components/pipeline_processors_editor/components/test_pipeline/test_pipeline_flyout.tsx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
EuiCallOut,
1717
} from '@elastic/eui';
1818

19-
import { Form, FormHook } from '../../../../../shared_imports';
19+
import { FormHook } from '../../../../../shared_imports';
2020
import { Document } from '../../types';
2121

2222
import { Tabs, TestPipelineFlyoutTab, OutputTab, DocumentsTab } from './test_pipeline_flyout_tabs';
@@ -71,19 +71,11 @@ export const TestPipelineFlyout: React.FunctionComponent<Props> = ({
7171
} else {
7272
// default to "Documents" tab
7373
tabContent = (
74-
<Form
74+
<DocumentsTab
7575
form={form}
76-
data-test-subj="testPipelineForm"
77-
isInvalid={form.isSubmitted && !form.isValid}
78-
onSubmit={validateAndTestPipeline}
79-
error={form.getErrors()}
80-
>
81-
<DocumentsTab
82-
validateAndTestPipeline={validateAndTestPipeline}
83-
isRunningTest={isRunningTest}
84-
isSubmitButtonDisabled={form.isSubmitted && !form.isValid}
85-
/>
86-
</Form>
76+
validateAndTestPipeline={validateAndTestPipeline}
77+
isRunningTest={isRunningTest}
78+
/>
8779
);
8880
}
8981

0 commit comments

Comments
 (0)