From f3039791d8404487c78a9e260edb6bc36cdecd20 Mon Sep 17 00:00:00 2001 From: Rob Fellows Date: Wed, 24 Jun 2026 16:02:16 -0400 Subject: [PATCH] NIFI-16047 - Queue listing: Ensure refresh spinner stops spinning when user cancels the load action --- .../queue-listing.reducer.spec.ts | 88 +++++++++++++++++++ .../queue-listing/queue-listing.reducer.ts | 7 +- 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.spec.ts diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.spec.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.spec.ts new file mode 100644 index 000000000000..dc01ff9e5231 --- /dev/null +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.spec.ts @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { queueListingReducer, initialState } from './queue-listing.reducer'; +import { + submitQueueListingRequest, + stopPollingQueueListingRequest, + deleteQueueListingRequestSuccess, + queueListingApiError, + resetQueueListingState +} from './queue-listing.actions'; +import { QueueListingState } from './index'; + +describe('queueListingReducer', () => { + describe('submitQueueListingRequest', () => { + it('should set status to loading', () => { + const next = queueListingReducer( + initialState, + submitQueueListingRequest({ request: { connectionId: 'conn-1' } as any }) + ); + + expect(next.status).toBe('loading'); + }); + }); + + describe('stopPollingQueueListingRequest', () => { + it('resets status to success when dispatched while loading (cancel flow)', () => { + const loadingState: QueueListingState = { ...initialState, status: 'loading' }; + + const next = queueListingReducer(loadingState, stopPollingQueueListingRequest()); + + expect(next.status).toBe('success'); + }); + + it('is a safe no-op when status is already success (normal completion path)', () => { + const successState: QueueListingState = { ...initialState, status: 'success' }; + + const next = queueListingReducer(successState, stopPollingQueueListingRequest()); + + expect(next.status).toBe('success'); + }); + }); + + describe('deleteQueueListingRequestSuccess', () => { + it('should clear the activeListingRequest', () => { + const stateWithActive: QueueListingState = { + ...initialState, + activeListingRequest: { id: 'req-1' } as any + }; + + const next = queueListingReducer(stateWithActive, deleteQueueListingRequestSuccess()); + + expect(next.activeListingRequest).toBeNull(); + }); + }); + + describe('queueListingApiError', () => { + it('should set status to error', () => { + const next = queueListingReducer(initialState, queueListingApiError({ error: 'oops' })); + + expect(next.status).toBe('error'); + }); + }); + + describe('resetQueueListingState', () => { + it('should reset to the initial state', () => { + const loadingState: QueueListingState = { ...initialState, status: 'loading' }; + + const next = queueListingReducer(loadingState, resetQueueListingState()); + + expect(next).toEqual(initialState); + }); + }); +}); diff --git a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.ts b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.ts index 7a6a15486ab4..0878a948aa60 100644 --- a/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.ts +++ b/nifi-frontend/src/main/frontend/apps/nifi/src/app/pages/queue/state/queue-listing/queue-listing.reducer.ts @@ -24,7 +24,8 @@ import { resetQueueListingState, queueListingApiError, loadConnectionLabelSuccess, - deleteQueueListingRequestSuccess + deleteQueueListingRequestSuccess, + stopPollingQueueListingRequest } from './queue-listing.actions'; import { produce } from 'immer'; @@ -79,6 +80,10 @@ export const queueListingReducer = createReducer( } }); }), + on(stopPollingQueueListingRequest, (state) => ({ + ...state, + status: 'success' as const + })), on(deleteQueueListingRequestSuccess, (state) => ({ ...state, activeListingRequest: null