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

[Composable template] Details panel + delete functionality #70814

Merged
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