Merge pull request #30311 from csuich2/issue-30300
fix(techdocs): handle undefined defaultPath in techdocs initial redirect
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Fixed an issue causing TechDocs to not properly handle initial redirect.
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2025 The Backstage Authors
|
||||
*
|
||||
* Licensed 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 { render } from '@testing-library/react';
|
||||
|
||||
// We need to mock react-router-dom hooks used by useInitialRedirect
|
||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||
|
||||
// Import the module from which the hook is defined
|
||||
import { useInitialRedirect } from './dom';
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useLocation: jest.fn(),
|
||||
useNavigate: jest.fn(),
|
||||
useParams: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('useInitialRedirect', () => {
|
||||
const mockNavigate = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset mocks before each test
|
||||
mockNavigate.mockReset();
|
||||
(useNavigate as jest.Mock).mockReturnValue(mockNavigate);
|
||||
(useLocation as jest.Mock).mockReturnValue({
|
||||
pathname: '/docs/default/Component/backstage-demo',
|
||||
});
|
||||
// Simulate that no current path is provided
|
||||
(useParams as jest.Mock).mockReturnValue({ '*': '' });
|
||||
});
|
||||
|
||||
const TestComponent: React.FC<{ defaultPath?: string }> = ({
|
||||
defaultPath,
|
||||
}) => {
|
||||
// Call hook that should trigger a redirect on mount only if defaultPath is a non-empty string.
|
||||
useInitialRedirect(defaultPath);
|
||||
return <div>Test</div>;
|
||||
};
|
||||
|
||||
it('should not navigate when defaultPath is undefined', () => {
|
||||
render(<TestComponent defaultPath={undefined} />);
|
||||
expect(mockNavigate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should navigate when defaultPath is a non-empty string', () => {
|
||||
render(<TestComponent defaultPath="/overview" />);
|
||||
expect(mockNavigate).toHaveBeenCalledWith(
|
||||
'/docs/default/Component/backstage-demo/overview',
|
||||
{ replace: true },
|
||||
);
|
||||
});
|
||||
|
||||
it('should not navigate if currPath is non-empty', () => {
|
||||
// Override useParams to simulate a non-empty currPath
|
||||
(useParams as jest.Mock).mockReturnValue({ '*': 'existing-path' });
|
||||
render(<TestComponent defaultPath={undefined} />);
|
||||
expect(mockNavigate).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -61,15 +61,13 @@ const MOBILE_MEDIA_QUERY = 'screen and (max-width: 76.1875em)';
|
||||
// If a defaultPath is specified then we should navigate to that path replacing the
|
||||
// current location in the history. This should only happen on the initial load so
|
||||
// navigating to the root of the docs doesn't also redirect.
|
||||
const useInitialRedirect = (defaultPath?: string) => {
|
||||
// const hasRun = useRef(false);
|
||||
|
||||
export const useInitialRedirect = (defaultPath?: string) => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { '*': currPath = '' } = useParams();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (currPath === '' && defaultPath !== '') {
|
||||
if (currPath === '' && defaultPath) {
|
||||
navigate(`${location.pathname}${defaultPath}`, { replace: true });
|
||||
}
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
Reference in New Issue
Block a user