1
0
Fork 0
mirror of https://github.com/mealie-recipes/mealie.git synced 2025-08-06 14:05:21 +02:00

feat: First Time Setup Wizard (#3204)

* extract user registration form into a composable

* added base wizard component

* added partial setup implementation

* removed unused attrs

* added setup bypass

* made setup page more readable

* add checkbox hints to autoform

* added common settings pages and initial submit logic

* bypass setup in demo

* add full name to user registration

* added fullname and pw handling to setup

* fixed wizard indentation

* added post-setup suggestions

* added tests for backend changes

* renamed Wizard to BaseWizard

* lint fixes

* pass hardcoded default password instead of backend nonsense

* removed old test

* fix e2e

* added setup skip to e2e testing for all admin users

---------

Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
This commit is contained in:
Michael Genson 2024-03-11 08:28:54 -05:00 committed by GitHub
parent 430e1d7d4e
commit 403038a5b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 1103 additions and 141 deletions

View file

@ -11,6 +11,8 @@ test('password login', async ({ page }) => {
await page.locator('div').filter({ hasText: /^Password$/ }).nth(3).click();
await page.getByLabel('Password').fill(password);
await page.getByRole('button', { name: 'Login', exact: true }).click();
// skip admin setup page
await page.getByRole('link', { name: "I'm already set up, just bring me to the homepage" }).click();
await expect(page.getByRole('navigation')).toContainText(name);
});
@ -40,6 +42,8 @@ test('ldap admin login', async ({ page }) => {
await page.locator('div').filter({ hasText: /^Password$/ }).nth(3).click();
await page.getByLabel('Password').fill(password);
await page.getByRole('button', { name: 'Login', exact: true }).click();
// skip admin setup page
await page.getByRole('link', { name: "I'm already set up, just bring me to the homepage" }).click();
await expect(page.getByRole('navigation')).toContainText(name);
await expect(page.getByRole('link', { name: 'Settings' })).toBeVisible();
});
@ -113,6 +117,8 @@ test('settings page verify oidc', async ({ page }) => {
await page.getByLabel('Password').click();
await page.getByLabel('Password').fill('MyPassword');
await page.getByRole('button', { name: 'Login', exact: true }).click();
// skip admin setup page
await page.getByRole('link', { name: "I'm already set up, just bring me to the homepage" }).click();
await page.getByRole('link', { name: 'Settings' }).click();
await page.getByRole('link', { name: 'Users' }).click();
await page.getByRole('cell', { name: username, exact: true }).click();
@ -135,6 +141,8 @@ test('oidc admin user', async ({ page }) => {
await page.getByPlaceholder('Enter any user/subject').fill(username);
await page.getByPlaceholder('Optional claims JSON value,').fill(JSON.stringify(claims));
await page.getByRole('button', { name: 'Sign-in' }).click();
// skip admin setup page
await page.getByRole('link', { name: "I'm already set up, just bring me to the homepage" }).click();
await expect(page.getByRole('navigation')).toContainText(name);
await expect(page.getByRole('link', { name: 'Settings' })).toBeVisible();
});

View file

@ -3,11 +3,14 @@ import json
import pytest
from fastapi.testclient import TestClient
from mealie.core.config import get_app_settings
from mealie.db.db_setup import session_context
from mealie.schema.user.user import PrivateUser
from mealie.repos.repository_factory import AllRepositories
from mealie.schema.response.pagination import PaginationQuery
from mealie.schema.user.user import ChangePassword, PrivateUser
from mealie.services.user_services.password_reset_service import PasswordResetService
from tests.utils import api_routes
from tests.utils.factories import random_string
from tests.utils.factories import random_email, random_string
from tests.utils.fixture_schemas import TestUser

View file

@ -9,6 +9,7 @@ def test_create_user_registration() -> None:
group_token=None,
email="SomeValidEmail@example.com",
username="SomeValidUsername",
full_name="SomeValidFullName",
password="SomeValidPassword",
password_confirm="SomeValidPassword",
advanced=False,
@ -20,6 +21,7 @@ def test_create_user_registration() -> None:
group_token="asdfadsfasdfasdfasdf",
email="SomeValidEmail@example.com",
username="SomeValidUsername",
full_name="SomeValidFullName",
password="SomeValidPassword",
password_confirm="SomeValidPassword",
advanced=False,
@ -35,6 +37,7 @@ def test_group_or_token_validator(group, group_token) -> None:
group_token=group_token,
email="SomeValidEmail@example.com",
username="SomeValidUsername",
full_name="SomeValidFullName",
password="SomeValidPassword",
password_confirm="SomeValidPassword",
advanced=False,
@ -47,6 +50,7 @@ def test_group_no_args_passed() -> None:
CreateUserRegistration(
email="SomeValidEmail@example.com",
username="SomeValidUsername",
full_name="SomeValidFullName",
password="SomeValidPassword",
password_confirm="SomeValidPassword",
advanced=False,
@ -61,6 +65,7 @@ def test_password_validator() -> None:
group_token="asdfadsfasdfasdfasdf",
email="SomeValidEmail@example.com",
username="SomeValidUsername",
full_name="SomeValidFullName",
password="SomeValidPassword",
password_confirm="PasswordDefNotMatch",
advanced=False,

View file

@ -25,6 +25,7 @@ def user_registration_factory(advanced=None, private=None) -> CreateUserRegistra
group=random_string(),
email=random_email(),
username=random_string(),
full_name=random_string(),
password="fake-password",
password_confirm="fake-password",
advanced=advanced or random_bool(),