import React from 'react'; import { renderWithRedux, patientlyWaitFor, fireEvent, within } from 'react-testing-lib-wrapper'; import { nockInstance, assertNockRequest, mockForemanAutocomplete } from '../../../../../test-utils/nockWrapper'; import katelloApi from '../../../../../services/api'; import mockDebsData from './installableDebs.fixtures.json'; import DebInstallModal from '../DebsTab/DebInstallModal'; import { HOST_INSTALLABLE_DEBS_KEY } from '../DebsTab/InstallableDebsConstants'; import { REX_FEATURES } from '../RemoteExecutionConstants'; jest.mock('../../hostDetailsHelpers', () => ({ ...jest.requireActual('../../hostDetailsHelpers'), userPermissionsFromHostDetails: () => ({ create_job_invocations: true, edit_hosts: true, }), })); const contentFacetAttributes = { id: 11, uuid: 'e5761ea3-4117-4ecf-83d0-b694f99b389e', content_view_default: false, lifecycle_environment_library: false, }; const renderOptions = (facetAttributes = contentFacetAttributes) => ({ apiNamespace: HOST_INSTALLABLE_DEBS_KEY, initialState: { API: { HOST_DETAILS: { response: { id: 1, name: 'test-host', content_facet_attributes: { ...facetAttributes }, }, status: 'RESOLVED', }, }, }, }); const hostInstallableDebs = katelloApi.getApiUrl('/debs'); const autocompleteUrl = '/hosts/1/debs/auto_complete_search'; const defaultQuery = { host_id: 1, per_page: 20, page: 1, packages_restrict_not_installed: true, packages_restrict_applicable: false, }; let firstPackages; beforeEach(() => { const { results } = mockDebsData; [firstPackages] = results; }); test('Can call API for installable deb packages and show on screen on page load', async (done) => { const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl); const scope = nockInstance .get(hostInstallableDebs) .query(defaultQuery) .reply(200, mockDebsData); const { getAllByText } = renderWithRedux(, renderOptions()); // Assert that the packages are now showing on the screen, but wait for them to appear. await patientlyWaitFor(() => expect(getAllByText(firstPackages.name)[0]).toBeInTheDocument()); // Assert request was made and completed, see helper function assertNockRequest(autocompleteScope); assertNockRequest(scope, done); // Pass jest callback to confirm test is done }); test('Can handle no installable deb packages being present', async (done) => { const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl); const noResults = { total: 0, subtotal: 0, page: 1, per_page: 20, results: [], }; const scope = nockInstance .get(hostInstallableDebs) .query(defaultQuery) .reply(200, noResults); const { queryByText } = renderWithRedux(, renderOptions()); // Assert that there are not any packages showing on the screen. await patientlyWaitFor(() => expect(queryByText('No packages available to install')).toBeInTheDocument()); // Assert request was made and completed, see helper function assertNockRequest(autocompleteScope); assertNockRequest(scope, done); // Pass jest callback to confirm test is done }); test('Can install a deb package via remote execution', async (done) => { const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl); const scope = nockInstance .get(hostInstallableDebs) .query(defaultQuery) .reply(200, mockDebsData); const triggerPackageInstall = jest.fn(); const { getAllByText, getByText, getByRole, } = renderWithRedux(, renderOptions()); await patientlyWaitFor(() => expect(getAllByText(firstPackages.name)[0]).toBeInTheDocument()); // find and select the first two packages const checkbox1 = getByRole('checkbox', { name: 'Select row 0' }); const checkbox2 = getByRole('checkbox', { name: 'Select row 1' }); fireEvent.click(checkbox1); fireEvent.click(checkbox2); // click the Install dropdown const footer = getByRole('contentinfo'); const dropdown = await patientlyWaitFor(() => within(footer).getByRole('button', { name: 'Select' })); fireEvent.click(dropdown); const rexOption = getByText('Install via remote execution'); fireEvent.click(rexOption); expect(triggerPackageInstall).toHaveBeenCalled(); assertNockRequest(autocompleteScope); assertNockRequest(scope, done); }); test('Can install a deb package via customized remote execution', async (done) => { const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl); const scope = nockInstance .get(hostInstallableDebs) .query(defaultQuery) .reply(200, mockDebsData); const { getAllByText, queryByText, getByRole, } = renderWithRedux(, renderOptions()); await patientlyWaitFor(() => expect(getAllByText(firstPackages.name)[0]).toBeInTheDocument()); // find and select the first two packages const checkbox1 = getByRole('checkbox', { name: 'Select row 0' }); const checkbox2 = getByRole('checkbox', { name: 'Select row 1' }); fireEvent.click(checkbox1); fireEvent.click(checkbox2); // click the Install dropdown const footer = getByRole('contentinfo'); const dropdown = await patientlyWaitFor(() => within(footer).getByRole('button', { name: 'Select' })); fireEvent.click(dropdown); const customizedRexOption = queryByText('Install via customized remote execution'); expect(customizedRexOption).toBeInTheDocument(); expect(customizedRexOption).toHaveAttribute( 'href', `/job_invocations/new?feature=${REX_FEATURES.KATELLO_PACKAGE_INSTALL}&search=name%20%5E%20(test-host)&inputs%5Bpackage%5D=duck,cheetah`, ); assertNockRequest(autocompleteScope); assertNockRequest(scope, done); }); test('Uses packages_install_by_search_query template when in select all mode', async (done) => { const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl); const scope = nockInstance .get(hostInstallableDebs) .query(defaultQuery) .reply(200, mockDebsData); const { getAllByText, queryByText, getByRole, } = renderWithRedux(, renderOptions()); await patientlyWaitFor(() => expect(getAllByText(firstPackages.name)[0]).toBeInTheDocument()); // find and click the select all checkbox const selectAllCheckbox = getByRole('checkbox', { name: 'Select all' }); fireEvent.click(selectAllCheckbox); // find and deselect the first package const checkbox1 = getByRole('checkbox', { name: 'Select row 0' }); fireEvent.click(checkbox1); // click the Install dropdown const footer = getByRole('contentinfo'); const dropdown = await patientlyWaitFor(() => within(footer).getByRole('button', { name: 'Select' })); fireEvent.click(dropdown); const customizedRexOption = queryByText('Install via customized remote execution'); expect(customizedRexOption).toBeInTheDocument(); expect(customizedRexOption).toHaveAttribute( 'href', `/job_invocations/new?feature=${REX_FEATURES.KATELLO_PACKAGE_INSTALL_BY_SEARCH}&search=name%20%5E%20(test-host)&inputs%5BPackage%20search%20query%5D=id%20!%5E%20(32376)`, ); assertNockRequest(autocompleteScope); assertNockRequest(scope, done); });