[#58] changed the error detection to prevent displaying error on first connection

This commit is contained in:
Camille Moussu
2025-08-22 10:26:51 +02:00
committed by Benoit TELLIER
parent a6c6f944a6
commit 4ba8be73b7
5 changed files with 45 additions and 35 deletions
+11 -10
View File
@@ -1,18 +1,21 @@
import { screen, waitFor } from "@testing-library/react";
import thunk from "redux-thunk";
import thunk, { ThunkDispatch } from "redux-thunk";
import HandleLogin from "../../../src/features/User/HandleLogin";
import * as oidcAuth from "../../../src/features/User/oidcAuth";
import { renderWithProviders } from "../../utils/Renderwithproviders";
import { clientConfig } from "../../../src/features/User/oidcAuth";
import * as apiUtils from "../../../src/utils/apiUtils";
clientConfig.url = "https://example.com";
import * as appHooks from "../../../src/app/hooks";
import { push } from "redux-first-history";
clientConfig.url = "https://example.com";
describe("HandleLogin", () => {
beforeEach(() => {
jest.spyOn(apiUtils, "redirectTo").mockImplementation(() => {});
jest.clearAllMocks();
jest.spyOn(apiUtils, "redirectTo").mockImplementation(() => {});
const dispatch = jest.fn() as ThunkDispatch<any, any, any>;
jest.spyOn(appHooks, "useAppDispatch").mockReturnValue(dispatch);
sessionStorage.clear();
});
@@ -37,8 +40,6 @@ describe("HandleLogin", () => {
);
expect(apiUtils.redirectTo).toHaveBeenCalledWith(loginUrlMock.redirectTo);
});
expect(screen.getByText(/error/i)).toBeInTheDocument();
});
test("shows Loading when userData exists and calendars pending is true", () => {
@@ -72,9 +73,9 @@ describe("HandleLogin", () => {
expect(screen.getByAltText("loading")).toBeInTheDocument();
});
test("shows Error when userData doesnt exists and calendars pending is false", () => {
renderWithProviders(<HandleLogin />);
expect(screen.getByText("Error")).toBeInTheDocument();
test("goes to error page when userData doesnt exists after loading and calendars pending is false", () => {
const dispatch = appHooks.useAppDispatch();
renderWithProviders(<HandleLogin />, { user: { loading: false } });
expect(dispatch).toHaveBeenCalledWith(push("/error"));
});
});
+2
View File
@@ -8,6 +8,7 @@ import "./App.css";
import { Loading } from "./components/Loading/Loading";
import HandleLogin from "./features/User/HandleLogin";
import CalendarApp from "./components/Calendar/Calendar";
import { Error } from "./components/Error/Error";
function App() {
return (
<Suspense fallback={<Loading />}>
@@ -24,6 +25,7 @@ function App() {
}
/>
<Route path="/callback" element={<CallbackResume />} />
<Route path="/error" element={<Error />} />
</Routes>
</Router>
</Suspense>
-3
View File
@@ -1,6 +1,3 @@
import React from "react";
import logo from "../../static/images/calendar.svg";
export function Error() {
return <p>Error</p>;
}
+5 -5
View File
@@ -7,12 +7,12 @@ import { push } from "redux-first-history";
import { redirectTo } from "../../utils/apiUtils";
export function HandleLogin() {
const userData = useAppSelector((state) => state.user.userData);
const userData = useAppSelector((state) => state.user);
const calendars = useAppSelector((state) => state.calendars);
const dispatch = useAppDispatch();
useEffect(() => {
const initiateLogin = async () => {
if (!userData) {
if (!userData.userData) {
const loginurl = await Auth();
sessionStorage.setItem(
@@ -30,10 +30,10 @@ export function HandleLogin() {
initiateLogin();
}, [userData]);
if (!userData) {
return <Error />;
if (!calendars.pending && !userData.loading) {
dispatch(push("/error"));
}
if (!calendars.pending) {
if (!calendars.pending && !userData.loading) {
dispatch(push("/calendar"));
}
return <Loading />;
+27 -17
View File
@@ -17,6 +17,7 @@ export const userSlice = createSlice({
userData: null as unknown as userData,
organiserData: null as unknown as userOrganiser,
tokens: null as unknown as Record<string, string>,
loading: true,
},
reducers: {
setUserData: (state, action) => {
@@ -24,29 +25,38 @@ export const userSlice = createSlice({
if (!state.organiserData) {
state.organiserData = {} as userOrganiser;
}
state.organiserData.cn = action.payload.name;
state.organiserData.cal_address = action.payload.email;
state.organiserData.cn = action.payload.sub;
state.organiserData.cal_address = `mailto:${action.payload.email}`;
state.loading = false;
},
setTokens: (state, action) => {
state.tokens = action.payload;
},
},
extraReducers: (builder) => {
builder.addCase(getOpenPaasUserDataAsync.fulfilled, (state, action) => {
state.userData.name = action.payload.firstname;
state.userData.family_name = action.payload.lastname;
state.userData.openpaasId = action.payload.id;
if (!state.organiserData) {
state.organiserData = {} as userOrganiser;
}
if (action.payload.firstname && action.payload.lastname) {
state.organiserData.cn = `${action.payload.firstname} ${action.payload.lastname}`;
}
if (action.payload.preferredEmail) {
state.organiserData.cal_address = action.payload.preferredEmail;
state.userData.email = action.payload.preferredEmail;
}
});
builder
.addCase(getOpenPaasUserDataAsync.fulfilled, (state, action) => {
state.loading = false;
state.userData.name = action.payload.firstname;
state.userData.family_name = action.payload.lastname;
state.userData.openpaasId = action.payload.id;
if (!state.organiserData) {
state.organiserData = {} as userOrganiser;
}
if (action.payload.firstname && action.payload.lastname) {
state.organiserData.cn = `${action.payload.firstname} ${action.payload.lastname}`;
}
if (action.payload.preferredEmail) {
state.organiserData.cal_address = action.payload.preferredEmail;
state.userData.email = action.payload.preferredEmail;
}
})
.addCase(getOpenPaasUserDataAsync.pending, (state) => {
state.loading = true;
})
.addCase(getOpenPaasUserDataAsync.rejected, (state) => {
state.loading = false;
});
},
});