Changes back-end unavailable to redirect to login instead of setup page
This commit is contained in:
@@ -9,7 +9,7 @@ export const handlers = [...authHandlers, ...userHandlers, ...setupHandlers, ...
|
|||||||
|
|
||||||
export { authHandlers } from './auth/handlers';
|
export { authHandlers } from './auth/handlers';
|
||||||
export { userHandlers } from './users/handlers';
|
export { userHandlers } from './users/handlers';
|
||||||
export { setupHandlers, setupUninitializedHandlers, setupConflictHandlers } from './setup/handlers';
|
export { setupHandlers, setupUninitializedHandlers, setupConflictHandlers, setupNetworkErrorHandlers } from './setup/handlers';
|
||||||
export { invitationHandlers } from './invitation/handlers';
|
export { invitationHandlers } from './invitation/handlers';
|
||||||
export { availabilityHandlers } from './availability/handlers';
|
export { availabilityHandlers } from './availability/handlers';
|
||||||
export * from './auth/fixtures';
|
export * from './auth/fixtures';
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ export const setupHandlers = [
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** Override: simulates network error on setup status — backend unreachable. */
|
||||||
|
export const setupNetworkErrorHandlers = [
|
||||||
|
http.get(`${API_BASE}/api/v1/Setup/status`, () => HttpResponse.error()),
|
||||||
|
];
|
||||||
|
|
||||||
/** Override: returns not-initialized status — use in tests for InitGuard. */
|
/** Override: returns not-initialized status — use in tests for InitGuard. */
|
||||||
export const setupUninitializedHandlers = [
|
export const setupUninitializedHandlers = [
|
||||||
http.get(`${API_BASE}/api/v1/Setup/status`, () =>
|
http.get(`${API_BASE}/api/v1/Setup/status`, () =>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
} from '@tanstack/react-router';
|
} from '@tanstack/react-router';
|
||||||
import type { AuthContextValue } from '@/contexts/auth-context';
|
import type { AuthContextValue } from '@/contexts/auth-context';
|
||||||
import type { SetupStatus } from '@/api/types';
|
import type { SetupStatus } from '@/api/types';
|
||||||
import { api } from '@/lib/api-client';
|
import { api, NetworkError } from '@/lib/api-client';
|
||||||
import { AppLayout } from '@/components/layout/AppLayout';
|
import { AppLayout } from '@/components/layout/AppLayout';
|
||||||
import { LoginPage } from '@/pages/LoginPage';
|
import { LoginPage } from '@/pages/LoginPage';
|
||||||
import { NotFoundPage } from '@/pages/NotFoundPage';
|
import { NotFoundPage } from '@/pages/NotFoundPage';
|
||||||
@@ -99,10 +99,13 @@ const rootRoute = createRootRouteWithContext<RouterContext>()({
|
|||||||
try {
|
try {
|
||||||
status = await fetchSetupStatus();
|
status = await fetchSetupStatus();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// On network failure, assume not initialized so the user can set up
|
if (err instanceof NetworkError) {
|
||||||
// the system once the backend is reachable. Logging helps debugging.
|
// Backend unreachable: skip setup redirect and show the login page instead.
|
||||||
console.warn('[InitGuard] Setup status check failed, assuming not initialized:', err);
|
status = { initialized: true };
|
||||||
status = { initialized: false };
|
} else {
|
||||||
|
console.warn('[InitGuard] Setup status check failed, assuming not initialized:', err);
|
||||||
|
status = { initialized: false };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSetup = location.pathname === '/setup';
|
const onSetup = location.pathname === '/setup';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { beforeEach, describe, expect, it } from 'vitest';
|
|||||||
import { screen } from '@testing-library/react';
|
import { screen } from '@testing-library/react';
|
||||||
import { renderApp, mockAuthenticated, mockGuest } from '@/test/utils';
|
import { renderApp, mockAuthenticated, mockGuest } from '@/test/utils';
|
||||||
import { server } from '@/mocks/server';
|
import { server } from '@/mocks/server';
|
||||||
import { setupUninitializedHandlers } from '@/mocks/index';
|
import { setupUninitializedHandlers, setupNetworkErrorHandlers } from '@/mocks/index';
|
||||||
import { _resetSetupStatusCache } from '@/router';
|
import { _resetSetupStatusCache } from '@/router';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -53,6 +53,24 @@ describe('InitGuard (BR-U2-09, BR-U2-10)', () => {
|
|||||||
expect(await screen.findByTestId('setup-submit-button')).toBeInTheDocument();
|
expect(await screen.findByTestId('setup-submit-button')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('shows login page (not setup) when backend is unreachable', async () => {
|
||||||
|
server.use(...setupNetworkErrorHandlers);
|
||||||
|
mockGuest();
|
||||||
|
renderApp('/login');
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('login-form-submit-button')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByTestId('setup-submit-button')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('redirects /setup to /login when backend is unreachable', async () => {
|
||||||
|
server.use(...setupNetworkErrorHandlers);
|
||||||
|
mockGuest();
|
||||||
|
renderApp('/setup');
|
||||||
|
|
||||||
|
expect(await screen.findByTestId('login-form-submit-button')).toBeInTheDocument();
|
||||||
|
expect(screen.queryByTestId('setup-submit-button')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
it('redirects /setup to /login when system is already initialized', async () => {
|
it('redirects /setup to /login when system is already initialized', async () => {
|
||||||
// Default handlers return { initialized: true }.
|
// Default handlers return { initialized: true }.
|
||||||
mockGuest();
|
mockGuest();
|
||||||
|
|||||||
Reference in New Issue
Block a user