Skip to content

Commit

Permalink
Up the codecov
Browse files Browse the repository at this point in the history
  • Loading branch information
marlonbaeten committed Jan 30, 2025
1 parent 6300949 commit 0e9a60a
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 14 deletions.
47 changes: 44 additions & 3 deletions backend/src/authentication/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ mod tests {
assert_eq!(result.user_id, 1);
assert_eq!(result.username, "user");

// logout the current user
let response = app
.clone()
.oneshot(
Expand All @@ -479,11 +480,12 @@ mod tests {

assert_eq!(response.status(), 200);

// try to get the current user again, should return 401
let response = app
.clone()
.oneshot(
Request::builder()
.method(Method::POST)
.method(Method::GET)
.uri("/api/user/whoami")
.header("cookie", &cookie)
.body(Body::empty())
Expand All @@ -492,7 +494,22 @@ mod tests {
.await
.unwrap();

assert_eq!(response.status(), 405);
assert_eq!(response.status(), 401);

// try to the current without any cookie, should return 401
let response = app
.clone()
.oneshot(
Request::builder()
.method(Method::GET)
.uri("/api/user/whoami")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), 401);
}

#[cfg(debug_assertions)]
Expand Down Expand Up @@ -687,7 +704,7 @@ mod tests {
.unwrap()
.to_string();

// Call the change password endpoint
// Call the change password endpoint with incorrect password
let response = app
.clone()
.oneshot(
Expand All @@ -710,5 +727,29 @@ mod tests {
.unwrap();

assert_eq!(response.status(), 401);

// Call the change password endpoint with incorrect ucer
let response = app
.clone()
.oneshot(
Request::builder()
.method(Method::POST)
.uri("/api/user/change-password")
.header(CONTENT_TYPE, "application/json")
.header("cookie", &cookie)
.body(Body::from(
serde_json::to_vec(&ChangePasswordRequest {
username: "wrong_user".to_string(),
password: "password".to_string(),
new_password: "new_password".to_string(),
})
.unwrap(),
))
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), 401);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("ChangePasswordForm", () => {

test("Successful change-password", async () => {
render(
<ApiProvider initialUser={true}>
<ApiProvider fetchInitialUser={true}>
<ChangePasswordForm />
</ApiProvider>,
);
Expand Down Expand Up @@ -57,9 +57,43 @@ describe("ChangePasswordForm", () => {
});
});

test("Incorrect password repeat in change-password form", async () => {
render(
<ApiProvider fetchInitialUser={true}>
<ChangePasswordForm />
</ApiProvider>,
);

overrideOnce("post", "/api/user/change-password", 401, {
error: "Invalid username and/or password",
fatal: false,
reference: "InvalidPassword",
});

const user = userEvent.setup();

await waitFor(() => {
expect(screen.getByText("Wachtwoord")).toBeVisible();
});

const password = screen.getByLabelText("Wachtwoord");
await user.type(password, "password");
const newPassword = screen.getByLabelText("Kies nieuw wachtwoord");
await user.type(newPassword, "password_new");
const repeatPassword = screen.getByLabelText("Herhaal het wachtwoord dat je net hebt ingevuld");
await user.type(repeatPassword, "password_new_wrong");

const submitButton = screen.getByRole("button", { name: "Opslaan" });
await user.click(submitButton);

await waitFor(async () => {
expect(await screen.findByText("De wachtwoorden komen niet overeen")).toBeVisible();
});
});

test("Unsuccessful change-password", async () => {
render(
<ApiProvider initialUser={true}>
<ApiProvider fetchInitialUser={true}>
<ChangePasswordForm />
</ApiProvider>,
);
Expand Down
25 changes: 25 additions & 0 deletions frontend/app/module/account/page/ChangePasswordPage.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { render } from "@testing-library/react";
import { beforeEach, describe, expect, test } from "vitest";

import { WhoAmIRequestHandler } from "@kiesraad/api-mocks";
import { Providers, screen, server, waitFor } from "@kiesraad/test";

import { ChangePasswordPage } from "./ChangePasswordPage";

describe("ChangePasswordPage", () => {
beforeEach(() => {
server.use(WhoAmIRequestHandler);
});

test("The change-password page should state the currently logged-in user", async () => {
render(
<Providers fetchInitialUser={true}>
<ChangePasswordPage />
</Providers>,
);

await waitFor(() => {
expect(screen.getByText("Gebruikersnaam: user")).toBeVisible();
});
});
});
6 changes: 3 additions & 3 deletions frontend/lib/api/ApiProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import useSessionState from "./useSessionState";

export interface ApiProviderProps {
children: ReactNode;
initialUser?: boolean;
fetchInitialUser?: boolean;
}

const client = new ApiClient();

export function ApiProvider({ children, initialUser = true }: ApiProviderProps) {
const { user, setUser } = useSessionState(initialUser);
export function ApiProvider({ children, fetchInitialUser = true }: ApiProviderProps) {
const { user, setUser } = useSessionState(fetchInitialUser);

// Unset the current user when the API returns a an invalid session error
// indicating that the sessions has expired or the user is not authenticated anymore
Expand Down
6 changes: 3 additions & 3 deletions frontend/lib/api/useSessionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ export interface SessionState {
// Keep track of the currently logged-in user
// By initially fetching the user data from the server
// and then updating it when the user logs in or out
export default function useSessionState(initialUser: boolean): SessionState {
export default function useSessionState(fetchInitialUser: boolean): SessionState {
const [user, setUser] = useState<LoginResponse | null>(null);

useEffect(() => {
if (initialUser) {
if (fetchInitialUser) {
const abortController = new AbortController();

void (async () => {
Expand All @@ -35,7 +35,7 @@ export default function useSessionState(initialUser: boolean): SessionState {
abortController.abort(DEFAULT_CANCEL_REASON);
};
}
}, [initialUser]);
}, [fetchInitialUser]);

return { user, setUser };
}
6 changes: 3 additions & 3 deletions frontend/lib/test/Providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import { getRouter, Router } from "./router";
export const Providers = ({
children,
router = getRouter(children),
initialUser = false,
fetchInitialUser = false,
}: {
children?: React.ReactNode;
router?: Router;
initialUser?: boolean;
fetchInitialUser?: boolean;
}) => {
return (
<ApiProvider initialUser={initialUser}>
<ApiProvider fetchInitialUser={fetchInitialUser}>
<RouterProvider router={router} />
</ApiProvider>
);
Expand Down

0 comments on commit 0e9a60a

Please sign in to comment.