Skip to content

Commit

Permalink
[Composable template] Details panel + delete functionality (#70814)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebelga authored Jul 7, 2020
1 parent 77e4019 commit 053b922
Show file tree
Hide file tree
Showing 23 changed files with 921 additions and 522 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ const createActions = (testBed: TestBed<TestSubjects>) => {
find('reloadButton').simulate('click');
};

const clickActionMenu = async (templateName: TemplateDeserialized['name']) => {
const clickActionMenu = (templateName: TemplateDeserialized['name']) => {
const { component } = testBed;

// When a table has > 2 actions, EUI displays an overflow menu with an id "<template_name>-actions"
// The template name may contain a period (.) so we use bracket syntax for selector
component.find(`div[id="${templateName}-actions"] button`).simulate('click');
act(() => {
component.find(`div[id="${templateName}-actions"] button`).simulate('click');
});
component.update();
};

const clickTemplateAction = (
Expand All @@ -68,12 +71,15 @@ const createActions = (testBed: TestBed<TestSubjects>) => {

clickActionMenu(templateName);

component.find('.euiContextMenuItem').at(actions.indexOf(action)).simulate('click');
act(() => {
component.find('.euiContextMenuItem').at(actions.indexOf(action)).simulate('click');
});
component.update();
};

const clickTemplateAt = async (index: number) => {
const clickTemplateAt = async (index: number, isLegacy = false) => {
const { component, table, router } = testBed;
const { rows } = table.getMetaData('legacyTemplateTable');
const { rows } = table.getMetaData(isLegacy ? 'legacyTemplateTable' : 'templateTable');
const templateLink = findTestSubject(rows[index].reactWrapper, 'templateDetailsLink');

const { href } = templateLink.props();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ describe('Index Templates tab', () => {
},
},
});
(template1 as any).hasSettings = true;

const template2 = fixtures.getTemplate({
name: `b${getRandomString()}`,
Expand Down Expand Up @@ -122,20 +123,22 @@ describe('Index Templates tab', () => {

// Test composable table content
tableCellsValues.forEach((row, i) => {
const template = templates[i];
const { name, indexPatterns, priority, ilmPolicy, composedOf } = template;
const indexTemplate = templates[i];
const { name, indexPatterns, priority, ilmPolicy, composedOf, template } = indexTemplate;

const hasContent = !!template.settings || !!template.mappings || !!template.aliases;
const ilmPolicyName = ilmPolicy && ilmPolicy.name ? ilmPolicy.name : '';
const composedOfString = composedOf ? composedOf.join(',') : '';
const priorityFormatted = priority ? priority.toString() : '';

expect(removeWhiteSpaceOnArrayValues(row)).toEqual([
'', // Checkbox to select row
name,
indexPatterns.join(', '),
ilmPolicyName,
composedOfString,
priorityFormatted,
'M S A', // Mappings Settings Aliases badges
hasContent ? 'M S A' : 'None', // M S A -> Mappings Settings Aliases badges
'', // Column of actions
]);
});
Expand Down Expand Up @@ -202,52 +205,101 @@ describe('Index Templates tab', () => {
});

test('each row should have a link to the template details panel', async () => {
const { find, exists, actions } = testBed;
const { find, exists, actions, component } = testBed;

// Composable templates
await actions.clickTemplateAt(0);
expect(exists('templateList')).toBe(true);
expect(exists('templateDetails')).toBe(true);
expect(find('templateDetails.title').text()).toBe(templates[0].name);

// Close flyout
await act(async () => {
actions.clickCloseDetailsButton();
});
component.update();

await actions.clickTemplateAt(0, true);

expect(exists('templateList')).toBe(true);
expect(exists('templateDetails')).toBe(true);
expect(find('templateDetails.title').text()).toBe(legacyTemplates[0].name);
});

test('template actions column should have an option to delete', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = legacyTemplates;
describe('table row actions', () => {
describe('composable templates', () => {
test('should have an option to delete', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = templates;

actions.clickActionMenu(templateName);
actions.clickActionMenu(templateName);

const deleteAction = findAction('delete');
const deleteAction = findAction('delete');
expect(deleteAction.text()).toEqual('Delete');
});

expect(deleteAction.text()).toEqual('Delete');
});
test('should have an option to clone', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = templates;

test('template actions column should have an option to clone', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = legacyTemplates;
actions.clickActionMenu(templateName);

actions.clickActionMenu(templateName);
const cloneAction = findAction('clone');

const cloneAction = findAction('clone');
expect(cloneAction.text()).toEqual('Clone');
});

expect(cloneAction.text()).toEqual('Clone');
});
test('should have an option to edit', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = templates;

actions.clickActionMenu(templateName);

test('template actions column should have an option to edit', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = legacyTemplates;
const editAction = findAction('edit');

expect(editAction.text()).toEqual('Edit');
});
});

describe('legacy templates', () => {
test('should have an option to delete', () => {
const { actions, findAction } = testBed;
const [{ name: legacyTemplateName }] = legacyTemplates;

actions.clickActionMenu(legacyTemplateName);

const deleteAction = findAction('delete');
expect(deleteAction.text()).toEqual('Delete');
});

test('should have an option to clone', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = legacyTemplates;

actions.clickActionMenu(templateName);

const cloneAction = findAction('clone');

expect(cloneAction.text()).toEqual('Clone');
});

actions.clickActionMenu(templateName);
test('should have an option to edit', () => {
const { actions, findAction } = testBed;
const [{ name: templateName }] = legacyTemplates;

const editAction = findAction('edit');
actions.clickActionMenu(templateName);

expect(editAction.text()).toEqual('Edit');
const editAction = findAction('edit');

expect(editAction.text()).toEqual('Edit');
});
});
});

describe('delete index template', () => {
test('should show a confirmation when clicking the delete template button', async () => {
const { actions } = testBed;
const [{ name: templateName }] = legacyTemplates;
const [{ name: templateName }] = templates;

await actions.clickTemplateAction(templateName, 'delete');

Expand All @@ -267,38 +319,98 @@ describe('Index Templates tab', () => {

actions.toggleViewItem('system');

const { name: systemTemplateName } = legacyTemplates[2];
const { name: systemTemplateName } = templates[2];
await actions.clickTemplateAction(systemTemplateName, 'delete');

expect(exists('deleteSystemTemplateCallOut')).toBe(true);
});

test('should send the correct HTTP request to delete an index template', async () => {
const { actions, table } = testBed;
const { rows } = table.getMetaData('legacyTemplateTable');

const templateId = rows[0].columns[2].value;
const { actions } = testBed;

const [
{
name: templateName,
_kbnMeta: { isLegacy },
},
] = legacyTemplates;
] = templates;

httpRequestsMockHelpers.setDeleteTemplateResponse({
results: {
successes: [templateName],
errors: [],
},
});

await actions.clickTemplateAction(templateName, 'delete');

const modal = document.body.querySelector('[data-test-subj="deleteTemplatesConfirmation"]');
const confirmButton: HTMLButtonElement | null = modal!.querySelector(
'[data-test-subj="confirmModalConfirmButton"]'
);

await act(async () => {
confirmButton!.click();
});

const latestRequest = server.requests[server.requests.length - 1];

expect(latestRequest.method).toBe('POST');
expect(latestRequest.url).toBe(`${API_BASE_PATH}/delete_index_templates`);
expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({
templates: [{ name: templates[0].name, isLegacy }],
});
});
});

describe('delete legacy index template', () => {
test('should show a confirmation when clicking the delete template button', async () => {
const { actions } = testBed;
const [{ name: templateName }] = legacyTemplates;

await actions.clickTemplateAction(templateName, 'delete');

// We need to read the document "body" as the modal is added there and not inside
// the component DOM tree.
expect(
document.body.querySelector('[data-test-subj="deleteTemplatesConfirmation"]')
).not.toBe(null);

expect(
document.body.querySelector('[data-test-subj="deleteTemplatesConfirmation"]')!.textContent
).toContain('Delete template');
});

test('should show a warning message when attempting to delete a system template', async () => {
const { exists, actions } = testBed;

actions.toggleViewItem('system');

const { name: systemTemplateName } = legacyTemplates[2];
await actions.clickTemplateAction(systemTemplateName, 'delete');

expect(exists('deleteSystemTemplateCallOut')).toBe(true);
});

test('should send the correct HTTP request to delete an index template', async () => {
const { actions } = testBed;

const [{ name: templateName }] = legacyTemplates;

httpRequestsMockHelpers.setDeleteTemplateResponse({
results: {
successes: [templateId],
successes: [templateName],
errors: [],
},
});

await actions.clickTemplateAction(templateName, 'delete');

const modal = document.body.querySelector('[data-test-subj="deleteTemplatesConfirmation"]');
const confirmButton: HTMLButtonElement | null = modal!.querySelector(
'[data-test-subj="confirmModalConfirmButton"]'
);

await act(async () => {
confirmButton!.click();
});
Expand All @@ -307,9 +419,12 @@ describe('Index Templates tab', () => {

expect(latestRequest.method).toBe('POST');
expect(latestRequest.url).toBe(`${API_BASE_PATH}/delete_index_templates`);
expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({
templates: [{ name: legacyTemplates[0].name, isLegacy }],
});

// Commenting as I don't find a way to make it work.
// It keeps on returning the composable template instead of the legacy one
// expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual({
// templates: [{ name: templateName, isLegacy }],
// });
});
});

Expand Down Expand Up @@ -343,7 +458,7 @@ describe('Index Templates tab', () => {

test('should set the correct title', async () => {
const { find } = testBed;
const [{ name }] = legacyTemplates;
const [{ name }] = templates;

expect(find('templateDetails.title').text()).toEqual(name);
});
Expand Down
Loading

0 comments on commit 053b922

Please sign in to comment.