import React from 'react';
import { renderWithRedux, patientlyWaitFor, fireEvent, act } from 'react-testing-lib-wrapper';
import { Route } from 'react-router-dom';
import { cvFilterDetailsKey } from '../../../ContentViewsConstants';
import {
nockInstance,
assertNockRequest,
mockAutocomplete,
} from '../../../../../test-utils/nockWrapper';
import api from '../../../../../services/api';
import CVContainerImageFilterContent from '../CVContainerImageFilterContent';
import cvFilterFixtures from './CVContainerImageFilterContent.fixtures.json';
import details from '../../../../ContentViews/__tests__/mockDetails.fixtures.json';
import emptyCVContainerImageData from './emptyCVContainerImageFilterContent.fixtures.json';
const afterDeleteFilterResultsArray = [...cvFilterFixtures.results];
afterDeleteFilterResultsArray.shift();
const { name: firstResultName } = cvFilterFixtures.results[0];
const { name: secondResultName } = cvFilterFixtures.results[1];
const cvFiltersUpdateDeletePath = api.getApiUrl('/content_view_filters/195/rules/35');
const cvFilterRulesPath = api.getApiUrl('/content_view_filters/195/rules');
const autocompleteNameUrl = '/docker_tags/auto_complete_name';
const addedRule = {
content_view_filter_id: 195,
id: 99,
name: 'walter',
created_at: '2021-08-20 13:11:21 -0600',
updated_at: '2021-08-20 13:11:21 -0600',
};
const autocompleteUrl = '/content_view_filters/195/rules/auto_complete_search';
const autocompleteQuery = {
organization_id: 1,
search: '',
};
const renderOptions = {
apiNamespace: cvFilterDetailsKey(13, 195),
routerParams: {
initialEntries: [{ pathname: '/content_views/13#/filters/195' }],
initialIndex: 1,
},
};
const withCVRoute = component => {component};
test('Can view container image filter rules', async (done) => {
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl, autocompleteQuery);
const cvFiltersScope = nockInstance
.get(cvFilterRulesPath)
.query(true)
.reply(200, cvFilterFixtures);
const { queryByText, getByLabelText } =
renderWithRedux(
withCVRoute(),
renderOptions,
);
// Nothing will show at first, page is loading
expect(queryByText(firstResultName)).not.toBeInTheDocument();
await patientlyWaitFor(() => {
expect(queryByText(firstResultName)).toBeInTheDocument();
expect(getByLabelText('Select all rows')).toBeInTheDocument();
getByLabelText('Select all rows').click();
});
await patientlyWaitFor(() => {
expect(getByLabelText('bulk_actions')).toBeInTheDocument();
getByLabelText('bulk_actions').click();
expect(getByLabelText('bulk_remove')).toHaveAttribute('aria-disabled', 'false');
});
assertNockRequest(autocompleteScope);
assertNockRequest(cvFiltersScope, done);
});
// Remove
test('Can remove filter rules', async (done) => {
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl, autocompleteQuery);
const cvFiltersScope = nockInstance
.get(cvFilterRulesPath)
.query(true)
.reply(200, cvFilterFixtures);
const cvFilterDeleteScope = nockInstance
.delete(cvFiltersUpdateDeletePath)
.reply(200, {});
const cvFiltersCallbackScope = nockInstance
.get(cvFilterRulesPath)
.query(true)
.reply(200, { ...cvFilterFixtures, results: afterDeleteFilterResultsArray });
const { queryByText, getAllByLabelText } =
renderWithRedux(
withCVRoute(),
renderOptions,
);
// Nothing will show at first, page is loading
expect(queryByText(firstResultName)).not.toBeInTheDocument();
await patientlyWaitFor(() => {
expect(queryByText(firstResultName)).toBeInTheDocument();
expect(getAllByLabelText('Actions')[0]).toHaveAttribute('aria-expanded', 'false');
});
fireEvent.click(getAllByLabelText('Actions')[0]);
await patientlyWaitFor(() => {
expect(getAllByLabelText('Actions')[0]).toHaveAttribute('aria-expanded', 'true');
expect(queryByText('Remove')).toBeInTheDocument();
fireEvent.click(queryByText('Remove'));
});
await patientlyWaitFor(() => {
expect(queryByText(secondResultName)).toBeInTheDocument();
expect(queryByText(firstResultName)).not.toBeInTheDocument();
});
assertNockRequest(autocompleteScope);
assertNockRequest(cvFiltersScope);
assertNockRequest(cvFilterDeleteScope);
assertNockRequest(cvFiltersCallbackScope, done);
});
// Add
test('Can add filter rules', async (done) => {
const autocompleteScope = mockAutocomplete(
nockInstance,
autocompleteUrl,
autocompleteQuery,
[],
2,
);
const autocompleteNameScope = mockAutocomplete(nockInstance, autocompleteNameUrl, true, [], 2);
const cvFiltersScope = nockInstance
.get(cvFilterRulesPath)
.times(2)
.query(true)
.reply(200, cvFilterFixtures);
const cvFilterAddScope = nockInstance
.post(cvFilterRulesPath)
.reply(200, addedRule);
const cvFiltersCallbackScope = nockInstance
.get(cvFilterRulesPath)
.query(true)
.reply(200, { ...cvFilterFixtures, results: [...cvFilterFixtures.results, addedRule] });
const { queryByText, getByLabelText, getAllByLabelText } =
renderWithRedux(
withCVRoute(),
renderOptions,
);
// Nothing will show at first, page is loading
expect(queryByText(firstResultName)).not.toBeInTheDocument();
await patientlyWaitFor(() => {
expect(queryByText(firstResultName)).toBeInTheDocument();
fireEvent.click(getByLabelText('add_filter_rule'));
});
await patientlyWaitFor(() => {
expect(getByLabelText('add_edit_filter_rule')).toBeInTheDocument();
expect(getByLabelText('add_edit_filter_rule')).toHaveAttribute('aria-disabled', 'true');
});
const searchInput = getAllByLabelText('Search input')[1];
searchInput.focus();
fireEvent.change(searchInput, { target: { value: 'new-rule' } });
fireEvent.submit(getByLabelText('add_edit_filter_rule'));
await patientlyWaitFor(() => {
expect(queryByText('Add rule')).not.toBeInTheDocument();
});
assertNockRequest(autocompleteScope);
assertNockRequest(cvFiltersScope);
assertNockRequest(cvFilterAddScope);
assertNockRequest(autocompleteNameScope);
assertNockRequest(cvFiltersCallbackScope, done);
act(done);
});
// Edit
test('Can edit filter rules', async (done) => {
const autocompleteScope = mockAutocomplete(
nockInstance,
autocompleteUrl,
autocompleteQuery,
[],
2,
);
const autocompleteNameScope = mockAutocomplete(nockInstance, autocompleteNameUrl, true, [], 2);
const cvFiltersScope = nockInstance
.get(cvFilterRulesPath)
.times(2)
.query(true)
.reply(200, cvFilterFixtures);
const cvFilterAddScope = nockInstance
.put(cvFiltersUpdateDeletePath)
.reply(200, addedRule);
const cvFiltersCallbackScope = nockInstance
.get(cvFilterRulesPath)
.query(true)
.reply(200, {
...cvFilterFixtures,
results: cvFilterFixtures.results.map((result) => {
if (result.name === firstResultName) {
return { ...result, name: addedRule.name };
}
return result;
}),
});
const {
queryByText, getAllByLabelText, getByLabelText,
} =
renderWithRedux(
withCVRoute(),
renderOptions,
);
// Nothing will show at first, page is loading
expect(queryByText(firstResultName)).not.toBeInTheDocument();
await patientlyWaitFor(() => {
expect(queryByText(firstResultName)).toBeInTheDocument();
expect(getAllByLabelText('Actions')[0]).toHaveAttribute('aria-expanded', 'false');
});
fireEvent.click(getAllByLabelText('Actions')[0]);
await patientlyWaitFor(() => {
expect(getAllByLabelText('Actions')[0]).toHaveAttribute('aria-expanded', 'true');
expect(queryByText('Edit')).toBeInTheDocument();
fireEvent.click(queryByText('Edit'));
});
await patientlyWaitFor(() => {
expect(getByLabelText('add_edit_filter_rule')).toBeInTheDocument();
expect(getByLabelText('add_edit_filter_rule')).toHaveAttribute('aria-disabled', 'false');
});
const searchInput = getAllByLabelText('Search input')[1];
searchInput.focus();
fireEvent.change(searchInput, { target: { value: 'changed-name' } });
fireEvent.submit(getByLabelText('add_edit_filter_rule'));
await patientlyWaitFor(() => {
expect(queryByText('Edit rule')).not.toBeInTheDocument();
});
assertNockRequest(autocompleteScope);
assertNockRequest(cvFiltersScope);
assertNockRequest(cvFilterAddScope);
assertNockRequest(autocompleteNameScope);
assertNockRequest(cvFiltersCallbackScope, done);
act(done);
});
test('Shows call-to-action when there are no filter rules', async (done) => {
const autocompleteScope = mockAutocomplete(
nockInstance,
autocompleteUrl,
autocompleteQuery,
[],
2,
);
const autocompleteNameScope = mockAutocomplete(nockInstance, autocompleteNameUrl, true, [], 2);
const cvFiltersScope = nockInstance
.get(cvFilterRulesPath)
.times(2)
.query(true)
.reply(200, emptyCVContainerImageData);
const { queryByLabelText, getAllByLabelText } =
renderWithRedux(
withCVRoute(),
renderOptions,
);
expect(queryByLabelText('add_filter_rule_empty_state')).toBeNull();
await patientlyWaitFor(() => expect(queryByLabelText('add_filter_rule_empty_state')).toBeInTheDocument());
fireEvent.click(queryByLabelText('add_filter_rule_empty_state'));
await patientlyWaitFor(() => {
expect(getAllByLabelText('Search input')[0]).toBeInTheDocument();
});
assertNockRequest(autocompleteScope);
assertNockRequest(autocompleteNameScope);
assertNockRequest(cvFiltersScope, done);
act(done);
});
test('Hides bulk_remove dropdownItem when there are no filter rules', async (done) => {
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl, autocompleteQuery);
const cvFiltersScope = nockInstance
.get(cvFilterRulesPath)
.query(true)
.reply(200, emptyCVContainerImageData);
const { queryByText, getByText, queryByLabelText } =
renderWithRedux(
withCVRoute(),
renderOptions,
);
expect(queryByText('Add filter rule')).toBeNull();
await patientlyWaitFor(() => {
expect(getByText('Add filter rule')).toBeInTheDocument();
expect(queryByLabelText('bulk_actions')).not.toBeInTheDocument();
});
assertNockRequest(autocompleteScope);
assertNockRequest(cvFiltersScope, done);
act(done);
});