Skip to content

Commit

Permalink
Address feedback and refine UX.
Browse files Browse the repository at this point in the history
- Add delete action to flyout.
- Always render the detail panel when deep-linked, even if table is loading, errored, or has no data streams.
- Fix tests and TS errors,
  • Loading branch information
cjcenizal committed Jun 24, 2020
1 parent 729228e commit 39f8aeb
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => {
]);
};

const setLoadDataStreamResponse = (response: HttpResponse = []) => {
server.respondWith('GET', `${API_BASE_PATH}/data_streams/:id`, [
200,
{ 'Content-Type': 'application/json' },
JSON.stringify(response),
]);
};

const setDeleteDataStreamResponse = (response: HttpResponse = []) => {
server.respondWith('POST', `${API_BASE_PATH}/delete_data_streams`, [
200,
Expand Down Expand Up @@ -88,6 +96,7 @@ const registerHttpRequestMockHelpers = (server: SinonFakeServer) => {
setLoadTemplatesResponse,
setLoadIndicesResponse,
setLoadDataStreamsResponse,
setLoadDataStreamResponse,
setDeleteDataStreamResponse,
setDeleteTemplateResponse,
setLoadTemplateResponse,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ export const setupEnvironment = () => {
export const WithAppDependencies = (Comp: any, overridingDependencies: any = {}) => (
props: any
) => {
const dependencies = merge(appDependencies, overridingDependencies);
const mergedDependencies = merge({}, appDependencies, overridingDependencies);
return (
<AppContextProvider value={appDependencies}>
<AppContextProvider value={mergedDependencies}>
<Comp {...props} />
</AppContextProvider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export interface DataStreamsTabTestBed extends TestBed<TestSubjects> {
clickIndicesAt: (index: number) => void;
clickDeletActionAt: (index: number) => void;
clickConfirmDelete: () => void;
clickDeletDataStreamButton: () => void;
};
findDeleteActionAt: (index: number) => ReactWrapper;
findDeleteConfirmationModal: () => ReactWrapper;
Expand Down Expand Up @@ -128,6 +129,11 @@ export const setup = async (overridingDependencies: any = {}): Promise<DataStrea
});
};

const clickDeletDataStreamButton = () => {
const { find } = testBed;
find('deleteDataStreamButton').simulate('click');
};

const findDetailPanel = () => {
const { find } = testBed;
return find('dataStreamDetailPanel');
Expand All @@ -148,6 +154,7 @@ export const setup = async (overridingDependencies: any = {}): Promise<DataStrea
clickIndicesAt,
clickDeletActionAt,
clickConfirmDelete,
clickDeletDataStreamButton,
},
findDeleteActionAt,
findDeleteConfirmationModal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,25 @@ describe('Data Streams tab', () => {
});

test('displays an empty prompt', async () => {
testBed = await setup();

await act(async () => {
testBed = await setup();
testBed.actions.goToDataStreamsList();
});

const { exists, component } = testBed;
testBed.component.update();
component.update();

expect(exists('sectionLoading')).toBe(false);
expect(exists('emptyPrompt')).toBe(true);
});

test('when Ingest Manager is disabled, goes to index templates tab when "Get started" link is clicked', async () => {
testBed = await setup({
plugins: {},
});

await act(async () => {
testBed = await setup({
plugins: {},
});
testBed.actions.goToDataStreamsList();
});

Expand All @@ -58,18 +60,19 @@ describe('Data Streams tab', () => {
});

test('when Ingest Manager is enabled, links to Ingest Manager', async () => {
testBed = await setup({
plugins: { ingestManager: { hi: 'ok' } },
});

await act(async () => {
testBed = await setup({
plugins: { ingestManager: {} },
});
testBed.actions.goToDataStreamsList();
});

const { findEmptyPromptIndexTemplateLink, component } = testBed;
component.update();

// Assert against the text because the href won't be available, due to dependency upon our core mock.
expect(findEmptyPromptIndexTemplateLink().props().children).toBe('Ingest Manager');
expect(findEmptyPromptIndexTemplateLink().text()).toBe('Ingest Manager');
});
});

Expand Down Expand Up @@ -101,13 +104,18 @@ describe('Data Streams tab', () => {
},
]);

const dataStreamForDetailPanel = createDataStreamPayload('dataStream1');

httpRequestsMockHelpers.setLoadDataStreamsResponse([
createDataStreamPayload('dataStream1'),
dataStreamForDetailPanel,
createDataStreamPayload('dataStream2'),
]);

httpRequestsMockHelpers.setLoadDataStreamResponse(dataStreamForDetailPanel);

testBed = await setup();

await act(async () => {
testBed = await setup();
testBed.actions.goToDataStreamsList();
});

Expand Down Expand Up @@ -138,13 +146,6 @@ describe('Data Streams tab', () => {
expect(server.requests[server.requests.length - 1].url).toBe(`${API_BASE_PATH}/data_streams`);
});

test('clicking the name opens the detail panel', async () => {
const { actions, findDetailPanel, findDetailPanelTitle } = testBed;
await actions.clickNameAt(0);
expect(findDetailPanel().length).toBe(1);
expect(findDetailPanelTitle()).toBe('dataStream1');
});

test('clicking the indices count navigates to the backing indices', async () => {
const { table, actions } = testBed;
await actions.clickIndicesAt(0);
Expand Down Expand Up @@ -196,5 +197,41 @@ describe('Data Streams tab', () => {
});
});
});

describe('detail panel', () => {
test('opens when the data stream name in the table is clicked', async () => {
const { actions, findDetailPanel, findDetailPanelTitle } = testBed;
await actions.clickNameAt(0);
expect(findDetailPanel().length).toBe(1);
expect(findDetailPanelTitle()).toBe('dataStream1');
});

test('deletes the data stream when delete button is clicked', async () => {
const {
actions: { clickNameAt, clickDeletDataStreamButton, clickConfirmDelete },
} = testBed;

await clickNameAt(0);

clickDeletDataStreamButton();

httpRequestsMockHelpers.setDeleteDataStreamResponse({
results: {
dataStreamsDeleted: ['dataStream1'],
errors: [],
},
});

await clickConfirmDelete();

const { method, url, requestBody } = server.requests[server.requests.length - 1];

expect(method).toBe('POST');
expect(url).toBe(`${API_BASE_PATH}/delete_data_streams`);
expect(JSON.parse(JSON.parse(requestBody).body)).toEqual({
dataStreams: ['dataStream1'],
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export interface IndicesTestBed extends TestBed<TestSubjects> {
clickIncludeHiddenIndicesToggle: () => void;
clickDataStreamAt: (index: number) => void;
};
findDataStreamDetailPanel: () => ReactWrapper;
findDataStreamDetailPanelTitle: () => string;
}

export const setup = async (): Promise<IndicesTestBed> => {
Expand Down Expand Up @@ -77,6 +79,16 @@ export const setup = async (): Promise<IndicesTestBed> => {
component.update();
};

const findDataStreamDetailPanel = () => {
const { find } = testBed;
return find('dataStreamDetailPanel');
};

const findDataStreamDetailPanelTitle = () => {
const { find } = testBed;
return find('dataStreamDetailPanelTitle').text();
};

return {
...testBed,
actions: {
Expand All @@ -85,5 +97,7 @@ export const setup = async (): Promise<IndicesTestBed> => {
clickIncludeHiddenIndicesToggle,
clickDataStreamAt,
},
findDataStreamDetailPanel,
findDataStreamDetailPanelTitle,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ describe('<IndexManagementHome />', () => {
},
]);

httpRequestsMockHelpers.setLoadDataStreamsResponse([
createDataStreamPayload('dataStream1'),
createDataStreamPayload('dataStream2'),
]);
// The detail panel should still appear even if there are no data streams.
httpRequestsMockHelpers.setLoadDataStreamsResponse([]);

httpRequestsMockHelpers.setLoadDataStreamResponse(createDataStreamPayload('dataStream1'));

testBed = await setup();

Expand All @@ -86,13 +86,17 @@ describe('<IndexManagementHome />', () => {
});

test('navigates to the data stream in the Data Streams tab', async () => {
const { table, actions } = testBed;
const {
table,
findDataStreamDetailPanel,
findDataStreamDetailPanelTitle,
actions = { clickDataStreamAt },
} = testBed;

await actions.clickDataStreamAt(0);

expect(table.getMetaData('dataStreamTable').tableCellsValues).toEqual([
['', 'dataStream1', '1', '@timestamp', '1'],
]);
expect(findDataStreamDetailPanel().length).toBe(1);
expect(findDataStreamDetailPanelTitle()).toBe('dataStream1');
});
});

Expand Down
Loading

0 comments on commit 39f8aeb

Please sign in to comment.