diff --git a/frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradePage.tsx b/frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradePage.tsx index 59389595c71..f9fc5c69857 100644 --- a/frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradePage.tsx +++ b/frontend/packages/helm-plugin/src/components/forms/install-upgrade/HelmInstallUpgradePage.tsx @@ -233,7 +233,7 @@ const HelmInstallUpgradePage: FC = () => { if (ns === ALL_NAMESPACES_KEY) { navigate(`/helm/all-namespaces`); } else if (ns !== namespace) { - navigate(`/helm/ns/${ns}`); + navigate(`/helm/ns/${ns}${location.search}`); } }; diff --git a/frontend/packages/helm-plugin/src/components/forms/install-upgrade/__tests__/HelmInstallUpgradePage.spec.tsx b/frontend/packages/helm-plugin/src/components/forms/install-upgrade/__tests__/HelmInstallUpgradePage.spec.tsx new file mode 100644 index 00000000000..3742acfa29e --- /dev/null +++ b/frontend/packages/helm-plugin/src/components/forms/install-upgrade/__tests__/HelmInstallUpgradePage.spec.tsx @@ -0,0 +1,132 @@ +import { screen, waitFor } from '@testing-library/react'; +import { renderWithProviders } from '@console/shared/src/test-utils/unit-test-utils'; +import HelmInstallUpgradePage from '../HelmInstallUpgradePage'; + +const mockNavigate = jest.fn(); +let capturedOnNamespaceChange: ((ns: string) => void) | undefined; + +jest.mock('react-router', () => ({ + ...jest.requireActual('react-router'), + useNavigate: () => mockNavigate, + useParams: () => ({ ns: 'test-ns' }), + useLocation: () => ({ + pathname: '/helm/ns/test-ns', + search: '?chartURL=https%3A%2F%2Fexample.com%2Fchart.tgz&indexEntry=test-chart--1.0.0', + hash: '', + state: null, + key: 'default', + }), +})); + +jest.mock('@console/dev-console/src/components/NamespacedPage', () => ({ + __esModule: true, + NamespacedPageVariants: { light: 'light' }, + default: ({ children, onNamespaceChange }: any) => { + capturedOnNamespaceChange = onNamespaceChange; + return
{children}
; + }, +})); + +jest.mock('@console/dynamic-plugin-sdk/src', () => ({ + useActivePerspective: () => ['admin'], +})); + +jest.mock('@console/internal/components/utils', () => ({ + LoadingBox: () =>
Loading...
, +})); + +jest.mock('@console/shared/src/components/document-title/DocumentTitle', () => ({ + DocumentTitle: ({ children }: any) => {children}, +})); + +jest.mock('@console/shared/src/utils/console-fetch', () => ({ + coFetchJSON: jest.fn(() => + Promise.resolve({ + chart: { + metadata: { name: 'test-chart', version: '1.0.0', appVersion: '1.0.0', annotations: {} }, + values: {}, + }, + }), + ), +})); + +jest.mock('../../../utils/helm-utils', () => ({ + getHelmActionConfig: jest.fn((_action, _release, ns, _t, _origin, chartURL, indexEntry) => ({ + type: 'install', + title: 'Install Helm Chart', + subTitle: '', + helmReleaseApi: `/api/helm/chart?url=${encodeURIComponent(chartURL || '')}&indexEntry=${indexEntry || ''}`, + fetch: jest.fn(), + redirectURL: `/topology/ns/${ns}`, + })), + getChartValuesYAML: jest.fn(() => ''), + getChartReadme: jest.fn(() => ''), + fetchHelmRelease: jest.fn(), + loadHelmManifestResources: jest.fn(() => []), + isGoingToTopology: jest.fn(() => true), +})); + +jest.mock('../../../utils/helm-validation-utils', () => ({ + getHelmActionValidationSchema: jest.fn(() => ({})), +})); + +jest.mock('../../url-chart/useBasicAuthSecretDropdown', () => ({ + NONE_SECRET_KEY: '__none__', +})); + +jest.mock('../HelmChartMetaDescription', () => ({ + __esModule: true, + default: () =>
Chart meta
, +})); + +jest.mock('../HelmInstallUpgradeForm', () => ({ + __esModule: true, + default: () =>
Helm form
, +})); + +describe('HelmInstallUpgradePage', () => { + beforeEach(() => { + mockNavigate.mockClear(); + capturedOnNamespaceChange = undefined; + }); + + it('should preserve query params when namespace changes', async () => { + renderWithProviders(); + + // Wait for chart data to load so NamespacedPage renders + await waitFor(() => { + expect(capturedOnNamespaceChange).toBeDefined(); + }); + + // Simulate namespace change via project dropdown + capturedOnNamespaceChange('new-ns'); + + expect(mockNavigate).toHaveBeenCalledWith( + '/helm/ns/new-ns?chartURL=https%3A%2F%2Fexample.com%2Fchart.tgz&indexEntry=test-chart--1.0.0', + ); + }); + + it('should not navigate when switching to same namespace', async () => { + renderWithProviders(); + + await waitFor(() => { + expect(capturedOnNamespaceChange).toBeDefined(); + }); + + capturedOnNamespaceChange('test-ns'); + + expect(mockNavigate).not.toHaveBeenCalled(); + }); + + it('should navigate to all-namespaces without query params', async () => { + renderWithProviders(); + + await waitFor(() => { + expect(capturedOnNamespaceChange).toBeDefined(); + }); + + capturedOnNamespaceChange('#ALL_NS#'); + + expect(mockNavigate).toHaveBeenCalledWith('/helm/all-namespaces'); + }); +});