11import React from 'react' ;
2- import {
3- render ,
4- screen ,
5- waitFor ,
6- fireEvent ,
7- within ,
8- cleanup ,
9- } from '@testing-library/react' ;
10- import '@testing-library/jest-dom/extend-expect' ;
112import { Provider } from 'react-redux' ;
12- import configureMockStore from 'redux-mock-store' ;
13- import thunk from 'redux-thunk' ;
3+ import { configureStore } from '@reduxjs/toolkit' ;
4+ import Immutable from 'seamless-immutable' ;
5+ import { render , screen , waitFor , fireEvent , within , cleanup } from '@testing-library/react' ;
6+ import '@testing-library/jest-dom' ;
147import { APIActions } from 'foremanReact/redux/API' ;
158import PreupgradeReportsTable from '../index' ;
169
1710jest . mock ( 'foremanReact/redux/API' ) ;
1811
12+ const mockReducer = ( state = Immutable ( { API : { } } ) ) => state ;
13+
1914jest . mock ( 'foremanReact/constants' , ( ) => ( {
2015 ...jest . requireActual ( 'foremanReact/constants' ) ,
2116 getControllerSearchProps : jest . fn ( ( ) => ( {
@@ -33,6 +28,7 @@ jest.mock('foremanReact/components/SearchBar', () => {
3328 const MockSearchBar = ( { onSearch, onChange } ) => (
3429 < input
3530 data-testid = "search-input"
31+ aria-label = "Search preupgrade report entries"
3632 onChange = { e => onChange && onChange ( e . target . value ) }
3733 onKeyDown = { e => {
3834 if ( e . key === 'Enter' ) onSearch ( e . target . value ) ;
@@ -42,7 +38,6 @@ jest.mock('foremanReact/components/SearchBar', () => {
4238 return MockSearchBar ;
4339} ) ;
4440
45- const mockStore = configureMockStore ( [ thunk ] ) ;
4641const mockJobId = 42 ;
4742const mockReportId = 999 ;
4843const mockJobData = {
@@ -72,14 +67,11 @@ const mockEntries = Array.from({ length: 12 }, (_, i) => ({
7267} ) ) ;
7368
7469describe ( 'PreupgradeReportsTable' , ( ) => {
75- let store ;
76-
7770 beforeEach ( ( ) => {
78- store = mockStore ( { API : { } } ) ;
7971 jest . clearAllMocks ( ) ;
8072
8173 APIActions . get . mockImplementation ( ( { key, handleSuccess } ) => {
82- return dispatch => {
74+ return ( ) => {
8375 if ( key . includes ( 'GET_LEAPP_REPORT_LIST' ) ) {
8476 handleSuccess ( { results : [ { id : mockReportId } ] } ) ;
8577 }
@@ -101,12 +93,16 @@ describe('PreupgradeReportsTable', () => {
10193 cleanup ( ) ;
10294 } ) ;
10395
104- const renderComponent = ( data = mockJobData ) =>
105- render (
96+ const renderComponent = ( data = mockJobData ) => {
97+ const store = configureStore ( {
98+ reducer : mockReducer ,
99+ } ) ;
100+ return render (
106101 < Provider store = { store } >
107102 < PreupgradeReportsTable data = { data } />
108103 </ Provider >
109104 ) ;
105+ } ;
110106
111107 const expandSection = ( ) => {
112108 fireEvent . click ( screen . getByText ( 'Leapp preupgrade report' ) ) ;
@@ -132,6 +128,9 @@ describe('PreupgradeReportsTable', () => {
132128 } ) ;
133129
134130 it ( 'refetches when status_label transitions (e.g. Running → Succeeded)' , async ( ) => {
131+ const store = configureStore ( {
132+ reducer : mockReducer ,
133+ } ) ;
135134 const { rerender } = render (
136135 < Provider store = { store } >
137136 < PreupgradeReportsTable
@@ -420,6 +419,43 @@ describe('PreupgradeReportsTable', () => {
420419 expect ( screen . getByRole ( 'button' , { name : 'Fix Selected' } ) ) . toBeDisabled ( ) ;
421420 } ) ;
422421
422+ it ( 'disables Fix Selected when selecting all on page with no fixable entries' , async ( ) => {
423+ APIActions . get . mockImplementation ( ( { key, handleSuccess } ) => {
424+ return ( ) => {
425+ if ( key . includes ( 'GET_LEAPP_REPORT_LIST' ) ) {
426+ handleSuccess ( { results : [ { id : mockReportId } ] } ) ;
427+ }
428+ if ( key . includes ( 'GET_LEAPP_REPORT_ENTRIES' ) ) {
429+ handleSuccess ( {
430+ id : mockReportId ,
431+ results : [
432+ {
433+ id : 999 ,
434+ title : 'Non-fixable Entry' ,
435+ hostname : 'test.com' ,
436+ host_id : 200 ,
437+ severity : 'low' ,
438+ summary : 'This has no command remediation' ,
439+ detail : {
440+ remediations : [ { type : 'hint' , context : 'Manual fix only' } ] ,
441+ } ,
442+ } ,
443+ ] ,
444+ total : 1 ,
445+ } ) ;
446+ }
447+ return { type : 'MOCK_API_SUCCESS' } ;
448+ } ;
449+ } ) ;
450+
451+ renderComponent ( ) ;
452+ expandSection ( ) ;
453+ await waitFor ( ( ) => screen . getByText ( 'Non-fixable Entry' , { selector : 'td' } ) ) ;
454+
455+ fireEvent . click ( screen . getByLabelText ( 'Select all' ) ) ;
456+ expect ( screen . getByRole ( 'button' , { name : 'Fix Selected' } ) ) . toBeDisabled ( ) ;
457+ } ) ;
458+
423459 it ( 'renders Run Upgrade button enabled when entries are present' , async ( ) => {
424460 renderComponent ( ) ;
425461 expandSection ( ) ;
0 commit comments