Strengthen setup password validation
- Add backend Pydantic password complexity validation for setup - Update frontend setup page with password rule feedback and strength indicator - Add/adjust setup API tests for password validation - Document setup password requirements - Fix frontend test type annotation issue
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import { render, screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { MemoryRouter, Routes, Route } from "react-router-dom";
|
||||
import { FluentProvider, webLightTheme } from "@fluentui/react-components";
|
||||
import { SetupPage } from "../SetupPage";
|
||||
@@ -10,9 +11,10 @@ vi.mock("../../api/setup", () => ({
|
||||
submitSetup: vi.fn(),
|
||||
}));
|
||||
|
||||
import { getSetupStatus } from "../../api/setup";
|
||||
import { getSetupStatus, submitSetup } from "../../api/setup";
|
||||
|
||||
const mockedGetSetupStatus = vi.mocked(getSetupStatus);
|
||||
const mockedSubmitSetup = vi.mocked(submitSetup);
|
||||
|
||||
function renderPage() {
|
||||
return render(
|
||||
@@ -59,6 +61,45 @@ describe("SetupPage", () => {
|
||||
expect(screen.queryByRole("progressbar")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("displays password complexity feedback while the user types", async () => {
|
||||
mockedGetSetupStatus.mockResolvedValue({ completed: false });
|
||||
renderPage();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByRole("heading", { name: /bangui setup/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const user = userEvent.setup();
|
||||
const passwordInput = screen.getByLabelText(/master password/i);
|
||||
await user.type(passwordInput, "Short1");
|
||||
|
||||
expect(screen.getByText(/2 of 4 rules satisfied/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/at least 8 characters/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/at least one uppercase letter/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/at least one special character/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not submit the form when the password is too weak", async () => {
|
||||
mockedGetSetupStatus.mockResolvedValue({ completed: false });
|
||||
mockedSubmitSetup.mockResolvedValue({ message: "Setup completed successfully. Please log in." });
|
||||
renderPage();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByRole("heading", { name: /bangui setup/i }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const user = userEvent.setup();
|
||||
await user.type(screen.getByLabelText(/master password/i), "Short1");
|
||||
await user.type(screen.getByLabelText(/confirm password/i), "Short1");
|
||||
await user.click(screen.getByRole("button", { name: /complete setup/i }));
|
||||
|
||||
expect(mockedSubmitSetup).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("redirects to /login when setup is already complete", async () => {
|
||||
mockedGetSetupStatus.mockResolvedValue({ completed: true });
|
||||
renderPage();
|
||||
|
||||
Reference in New Issue
Block a user