Katello/katello

View on GitHub
webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js

Summary

Maintainability
D
2 days
Test Coverage
import React from 'react';
import { renderWithRedux, patientlyWaitFor, fireEvent, act } from 'react-testing-lib-wrapper';
import { Route } from 'react-router-dom';

import ContentViewFilterDetails from '../ContentViewFilterDetails';
import { cvFilterDetailsKey } from '../../../ContentViewsConstants';
import {
  nockInstance,
  assertNockRequest,
  mockAutocomplete,
} from '../../../../../test-utils/nockWrapper';
import api from '../../../../../services/api';
import cvFilterDetails from './cvPackageFilterDetail.fixtures.json';
import cvPackageFilterRules from './cvPackageFilterRules.fixtures.json';
import cvFilterFixtures from './contentViewFilters.fixtures.json';
import details from '../../../__tests__/mockDetails.fixtures.json';
// import emptyContentViewFiltersData from './emptyContentViewFilters.fixtures.json';
import emptyCVPackageFilterRules from './emptyCVPackageFilterRules.fixtures.json';

const cvFiltersPath = api.getApiUrl('/content_view_filters');
const cvFilterDetailsPath = api.getApiUrl('/content_view_filters/2');
const cvFilterEditDeletePath = api.getApiUrl('/content_view_filters/2/rules/2');
const cvPackageFilterRulesPath = api.getApiUrl('/content_view_filters/2/rules');
const cvPackageFilterRuleCreatePath = api.getApiUrl('/content_view_filters/2/rules');
const autocompleteUrl = '/content_view_filters/2/rules/auto_complete_search';
const autocompleteNameUrl = '/packages/auto_complete_name';
const autocompleteArchUrl = '/packages/auto_complete_arch';
const renderOptions = {
  apiNamespace: cvFilterDetailsKey(1, 2),
  routerParams: {
    initialEntries: [{ pathname: '/content_views/1#/filters/2', hash: '#/filters' }],
    initialIndex: 1,
  },
};
const autocompleteQuery = {
  organization_id: 1,
  search: '',
};

const withCVRoute = component => <Route path="/content_views/:id([0-9]+)#/filters/:filterId([0-9]+)">{component}</Route>;

test('Can show filter details and package groups on page load', async (done) => {
  const { name: cvFilterName } = cvFilterDetails;
  const cvFilterScope = nockInstance
    .get(cvFilterDetailsPath)
    .query(true)
    .reply(200, cvFilterDetails);
  const cvFiltersScope = nockInstance
    .get(cvFiltersPath)
    .query(true)
    .reply(200, cvFilterFixtures);
  const cvPackageFilterRulesScope = nockInstance
    .get(cvPackageFilterRulesPath)
    .query(true)
    .reply(200, cvPackageFilterRules);
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl, autocompleteQuery);

  const { getByText, queryByText } =
    renderWithRedux(withCVRoute(<ContentViewFilterDetails
      cvId={1}
      details={details}
    />), renderOptions);

  // Nothing will show at first, page is loading
  expect(queryByText(cvFilterName)).toBeNull();
  await patientlyWaitFor(() => {
    expect(getByText(cvFilterName)).toBeInTheDocument();
  });

  assertNockRequest(autocompleteScope);
  assertNockRequest(cvFilterScope);
  assertNockRequest(cvFiltersScope);
  assertNockRequest(cvPackageFilterRulesScope);
  act(done);
});

test('Can search for package rules in package filter details', async (done) => {
  const firstPackageRule = cvPackageFilterRules.results[0];
  const lastPackageRule = cvPackageFilterRules.results[1];
  const { name: cvFilterName } = cvFilterDetails;
  const { name: firstPackageRuleName } = firstPackageRule;
  const { name: lastPackageRuleName } = lastPackageRule;
  const searchQueryMatcher = {
    organization_id: 1,
    search: `name = ${lastPackageRuleName}`,
  };
  const searchResults = [
    {
      completed: `name = ${lastPackageRuleName}`,
      part: 'and',
      label: `name = ${lastPackageRuleName} and`,
      category: 'Operators',
    },
    {
      completed: `name = ${lastPackageRuleName}`,
      part: 'or',
      label: `name = ${lastPackageRuleName} or`,
      category: 'Operators',
    },
  ];

  const cvFilterScope = nockInstance
    .get(cvFilterDetailsPath)
    .query(true)
    .reply(200, cvFilterDetails);
  const cvFiltersScope = nockInstance
    .get(cvFiltersPath)
    .query(true)
    .reply(200, cvFilterFixtures);
  const cvPackageFilterRulesScope = nockInstance
    .get(cvPackageFilterRulesPath)
    .query(true)
    .reply(200, cvPackageFilterRules);
  const packageRuleSearchScope = nockInstance
    .get(cvPackageFilterRulesPath)
    .query(searchQueryMatcher)
    .reply(200, { results: [lastPackageRule] });

  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl, autocompleteQuery);
  const withSearchScope = mockAutocomplete(
    nockInstance,
    autocompleteUrl,
    searchQueryMatcher,
    searchResults,
  );
  const { getByText, queryByText, getByLabelText } =
    renderWithRedux(withCVRoute(<ContentViewFilterDetails
      cvId={1}
      details={details}
    />), renderOptions);
  // Basic results showing
  await patientlyWaitFor(() => {
    expect(getByText(cvFilterName)).toBeInTheDocument();
    expect(getByText(firstPackageRuleName)).toBeInTheDocument();
  });

  // Search and only searched result shows
  getByLabelText('Search input').focus();
  fireEvent.change(getByLabelText('Search input'), { target: { value: `name = ${lastPackageRuleName}` } });
  await patientlyWaitFor(() => {
    expect(getByText(`name = ${lastPackageRuleName} and`)).toBeInTheDocument();
    expect(queryByText(`name = ${firstPackageRuleName} and`)).not.toBeInTheDocument();
  });

  assertNockRequest(autocompleteScope);
  assertNockRequest(cvFilterScope);
  assertNockRequest(cvFiltersScope);
  assertNockRequest(cvPackageFilterRulesScope);
  assertNockRequest(withSearchScope);
  assertNockRequest(packageRuleSearchScope);
  act(done);
});

test('Can add package rules to filter in a self-closing modal', async (done) => {
  const { name: cvFilterName } = cvFilterDetails;
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl, true, undefined, 2);
  const autocompleteNameScope = mockAutocomplete(
    nockInstance, autocompleteNameUrl, true,
    undefined, 2,
  );
  const autocompleteArchScope = mockAutocomplete(
    nockInstance, autocompleteArchUrl, true,
    undefined, 2,
  );

  const cvFiltersScope = nockInstance
    .get(cvFiltersPath)
    .query(true)
    .reply(200, cvFilterFixtures);
  const cvFilterDetailsScope = nockInstance
    .get(cvFilterDetailsPath)
    .query(true)
    .reply(200, cvFilterDetails);
  const cvPackageFilterRulesScope = nockInstance
    .get(cvPackageFilterRulesPath)
    .times(2) // One on initial page load and one after rule create
    .query(true)
    .reply(200, cvPackageFilterRules);

  const newFilterRuleDetails = {
    architecture: 'noarch',
    name: 'elephant',
  };

  const createdFilterDetails = {
    architecture: 'noarch',
    content_view_filter_id: 1,
    created_at: '2021-08-06 06:12:10 -0400',
    id: 3,
    name: 'elephant',
    updated_at: '2021-08-06 06:12:10 -0400',
  };

  const createscope = nockInstance
    .post(cvPackageFilterRuleCreatePath, newFilterRuleDetails)
    .reply(201, createdFilterDetails);

  const {
    getByText, queryByText, getByLabelText, getAllByLabelText,
  } =
    renderWithRedux(withCVRoute(<ContentViewFilterDetails
      cvId={1}
      details={details}
    />), renderOptions);

  // Nothing will show at first, page is loading
  expect(queryByText(cvFilterName)).toBeNull();
  await patientlyWaitFor(() => {
    expect(getByText(cvFilterName)).toBeInTheDocument();
    expect(getByLabelText('add_rpm_rule')).toBeInTheDocument();
  });
  getByLabelText('add_rpm_rule').click();
  await patientlyWaitFor(() => {
    expect(getAllByLabelText('Search input')[0]).toBeInTheDocument();
    expect(getAllByLabelText('Search input')[1]).toBeInTheDocument();
    expect(getByLabelText('add_package_filter_rule')).toBeInTheDocument();
  });
  const nameSearchInput = getAllByLabelText('Search input')[1];
  const archSearchInput = getAllByLabelText('Search input')[2];
  nameSearchInput.focus();
  fireEvent.change(nameSearchInput, { target: { value: 'elephant' } });
  archSearchInput.focus();
  fireEvent.change(archSearchInput, { target: { value: 'noarch' } });
  fireEvent.submit(getByLabelText('add_package_filter_rule'));

  await patientlyWaitFor(() => {
    expect(queryByText('Add rule')).not.toBeInTheDocument();
  });
  assertNockRequest(autocompleteScope);
  assertNockRequest(autocompleteNameScope);
  assertNockRequest(autocompleteArchScope);
  assertNockRequest(cvFiltersScope);
  assertNockRequest(cvFilterDetailsScope);
  assertNockRequest(cvPackageFilterRulesScope);
  assertNockRequest(createscope);
  assertNockRequest(cvPackageFilterRulesScope);
  act(done);
});

test('Remove rpm filter rule in a self-closing modal', async (done) => {
  const { name: cvFilterName } = cvFilterDetails;
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);

  const cvFiltersScope = nockInstance
    .get(cvFiltersPath)
    .query(true)
    .reply(200, cvFilterFixtures);
  const cvFilterDetailsScope = nockInstance
    .get(cvFilterDetailsPath)
    .query(true)
    .reply(200, cvFilterDetails);
  const cvPackageFilterRulesScope = nockInstance
    .get(cvPackageFilterRulesPath)
    .times(2) // One on initial page load and one after rule create
    .query(true)
    .reply(200, cvPackageFilterRules);

  const removeScope = nockInstance
    .delete(cvFilterEditDeletePath)
    .reply(201, {});


  const { getByText, queryByText, getAllByLabelText } =
    renderWithRedux(withCVRoute(<ContentViewFilterDetails
      cvId={1}
      details={details}
    />), renderOptions);

  // Nothing will show at first, page is loading
  expect(queryByText(cvFilterName)).toBeNull();
  await patientlyWaitFor(() => {
    expect(getByText(cvFilterName)).toBeInTheDocument();
    expect(getAllByLabelText('Actions')[1]).toBeInTheDocument();
  });

  getAllByLabelText('Actions')[1].click();

  await patientlyWaitFor(() => {
    expect(getByText('Remove')).toBeInTheDocument();
  });

  getByText('Remove').click();
  await patientlyWaitFor(() => {
    expect(getByText(cvFilterName)).toBeInTheDocument();
    expect(getAllByLabelText('Actions')[1]).toBeInTheDocument();
  });

  assertNockRequest(autocompleteScope);
  assertNockRequest(cvFiltersScope);
  assertNockRequest(cvFilterDetailsScope);
  assertNockRequest(cvPackageFilterRulesScope);
  assertNockRequest(removeScope);
  assertNockRequest(cvPackageFilterRulesScope);
  act(done);
});

test('Edit rpm filter rule in a self-closing modal', async (done) => {
  const { name: cvFilterName } = cvFilterDetails;
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl, true, undefined, 2);
  const autocompleteNameScope = mockAutocomplete(
    nockInstance, autocompleteNameUrl, true,
    undefined, 2,
  );
  const autocompleteArchScope = mockAutocomplete(
    nockInstance, autocompleteArchUrl, true,
    undefined, 2,
  );
  const cvFiltersScope = nockInstance
    .get(cvFiltersPath)
    .times(2)
    .query(true)
    .reply(200, cvFilterFixtures);
  const cvFilterDetailsScope = nockInstance
    .get(cvFilterDetailsPath)
    .times(2)
    .query(true)
    .reply(200, cvFilterDetails);
  const cvPackageFilterRulesScope = nockInstance
    .persist()
    .get(cvPackageFilterRulesPath)
    .query(true)
    .reply(200, cvPackageFilterRules);

  const editScope = nockInstance
    .put(cvFilterEditDeletePath)
    .query(true)
    .reply(201, {});

  const {
    getByText, queryByText, getAllByLabelText, getByLabelText,
  } =
    renderWithRedux(withCVRoute(<ContentViewFilterDetails
      cvId={1}
      details={details}
    />), renderOptions);

  // Nothing will show at first, page is loading
  expect(queryByText(cvFilterName)).toBeNull();
  await patientlyWaitFor(() => {
    expect(getByText(cvFilterName)).toBeInTheDocument();
    expect(getAllByLabelText('Actions')[1]).toBeInTheDocument();
  });

  getAllByLabelText('Actions')[1].click();

  await patientlyWaitFor(() => {
    expect(getByText('Edit')).toBeInTheDocument();
  });

  getByText('Edit').click();

  await patientlyWaitFor(() => {
    expect(getByText('Edit RPM rule')).toBeInTheDocument();
  });
  fireEvent.submit(getByLabelText('add_package_filter_rule'));
  await patientlyWaitFor(() => {
    expect(queryByText('Edit RPM rule')).not.toBeInTheDocument();
    expect(getByText(cvFilterName)).toBeInTheDocument();
  });

  assertNockRequest(autocompleteScope);
  assertNockRequest(autocompleteNameScope);
  assertNockRequest(autocompleteArchScope);
  assertNockRequest(cvFiltersScope);
  assertNockRequest(cvFilterDetailsScope);
  assertNockRequest(cvPackageFilterRulesScope);
  assertNockRequest(editScope);
  act(done);
});

test('Shows call-to-action when there are no RPM filters', async (done) => {
  const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
  const autocompleteNameScope = mockAutocomplete(nockInstance, autocompleteNameUrl);
  const autocompleteArchScope = mockAutocomplete(nockInstance, autocompleteArchUrl);
  const cvFilterDetailScope = nockInstance
    .get(cvFilterDetailsPath)
    .query(true)
    .reply(200, cvFilterDetails);
  const cvFiltersScope = nockInstance
    .get(cvFiltersPath)
    .query(true)
    .reply(200, cvFilterFixtures);
  const cvPackageFilterRulesScope = nockInstance
    .get(cvPackageFilterRulesPath)
    .times(1)
    .query(true)
    .reply(200, emptyCVPackageFilterRules);
  const {
    queryByLabelText, queryByText, getAllByLabelText,
  } =
    renderWithRedux(withCVRoute(<ContentViewFilterDetails
      cvId={1}
      details={details}
    />), renderOptions);
  expect(queryByLabelText('add_rpm_rule_empty_state')).not.toBeInTheDocument();
  await patientlyWaitFor(() => expect(queryByLabelText('add_rpm_rule_empty_state')).toBeInTheDocument());
  fireEvent.click(queryByLabelText('add_rpm_rule_empty_state'));

  await patientlyWaitFor(() => {
    expect(getAllByLabelText('Search input')[0]).toBeInTheDocument();
    expect(queryByText('Cancel')).toBeInTheDocument();
  });
  fireEvent.click(queryByText('Cancel'));
  await patientlyWaitFor(() => {
    expect(queryByLabelText('add-edit-package-modal-cancel')).not.toBeInTheDocument();
  });
  assertNockRequest(autocompleteNameScope);
  assertNockRequest(autocompleteArchScope);
  assertNockRequest(autocompleteScope);
  assertNockRequest(cvFiltersScope);
  assertNockRequest(cvFilterDetailScope);
  assertNockRequest(cvPackageFilterRulesScope);
  act(done);
});