123 lines
4.4 KiB
Rust
123 lines
4.4 KiB
Rust
use galaxy_core::user_preferences::GetUserPreferences as _;
|
|
use galaxyui::{App, SingletonEntity};
|
|
|
|
use super::{has_completed_local_onboarding, RootView, HAS_COMPLETED_ONBOARDING_KEY};
|
|
use crate::auth::auth_manager::AuthManager;
|
|
use crate::auth::AuthStateProvider;
|
|
use crate::server::server_api::ServerApiProvider;
|
|
|
|
fn initialize_app(app: &mut App) {
|
|
app.update(crate::settings::init_and_register_user_preferences);
|
|
app.add_singleton_model(|_ctx| ServerApiProvider::new_for_test());
|
|
app.add_singleton_model(|_| AuthStateProvider::new_for_test());
|
|
app.add_singleton_model(AuthManager::new_for_test);
|
|
}
|
|
|
|
fn set_local_onboarding_completed(app: &mut App, completed: bool) {
|
|
app.update(|ctx| {
|
|
ctx.private_user_preferences()
|
|
.write_value(
|
|
HAS_COMPLETED_ONBOARDING_KEY,
|
|
serde_json::to_string(&completed).unwrap(),
|
|
)
|
|
.unwrap();
|
|
});
|
|
}
|
|
|
|
/// Regression test for the bug fixed by introducing
|
|
/// `RootView::sync_local_onboarding_to_server`: when a user completed onboarding
|
|
/// pre-login and later authenticated via a non-login-slide entrypoint (i.e. while
|
|
/// already in `Terminal` state), the server-side `is_onboarded` flag was never
|
|
/// flipped. The helper runs unconditionally on `AuthComplete` and must flip the
|
|
/// flag when all preconditions hold.
|
|
#[test]
|
|
fn test_sync_flips_server_is_onboarded_when_local_onboarding_completed() {
|
|
App::test((), |mut app| async move {
|
|
initialize_app(&mut app);
|
|
|
|
// Seed the "has_completed_local_onboarding" preference and make the user
|
|
// appear not yet onboarded on the server. The default test user is
|
|
// non-anonymous, so the guards in the helper won't short-circuit.
|
|
set_local_onboarding_completed(&mut app, true);
|
|
app.update(|ctx| {
|
|
AuthStateProvider::as_ref(ctx).get().set_is_onboarded(false);
|
|
assert!(has_completed_local_onboarding(ctx));
|
|
assert_eq!(
|
|
AuthStateProvider::as_ref(ctx).get().is_onboarded(),
|
|
Some(false)
|
|
);
|
|
});
|
|
|
|
app.update(|ctx| {
|
|
let auth_state = AuthStateProvider::as_ref(ctx).get().clone();
|
|
RootView::sync_local_onboarding_to_server(&auth_state, ctx);
|
|
});
|
|
|
|
app.read(|ctx| {
|
|
assert_eq!(
|
|
AuthStateProvider::as_ref(ctx).get().is_onboarded(),
|
|
Some(true),
|
|
"sync should have invoked AuthManager::set_user_onboarded"
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
/// If the user hasn't completed local onboarding, the helper must leave the
|
|
/// server-side flag untouched — onboarding hasn't actually happened yet.
|
|
#[test]
|
|
fn test_sync_noop_when_local_onboarding_not_completed() {
|
|
App::test((), |mut app| async move {
|
|
initialize_app(&mut app);
|
|
|
|
// Do not set HAS_COMPLETED_ONBOARDING_KEY; it defaults to false.
|
|
app.update(|ctx| {
|
|
AuthStateProvider::as_ref(ctx).get().set_is_onboarded(false);
|
|
});
|
|
|
|
app.update(|ctx| {
|
|
let auth_state = AuthStateProvider::as_ref(ctx).get().clone();
|
|
RootView::sync_local_onboarding_to_server(&auth_state, ctx);
|
|
});
|
|
|
|
app.read(|ctx| {
|
|
assert_eq!(
|
|
AuthStateProvider::as_ref(ctx).get().is_onboarded(),
|
|
Some(false),
|
|
"sync should not have changed is_onboarded when local onboarding is incomplete"
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
/// The server-side flag should also be left untouched when it is already set,
|
|
/// even if local onboarding is complete — avoids redundant server calls.
|
|
#[test]
|
|
fn test_sync_noop_when_already_onboarded_on_server() {
|
|
App::test((), |mut app| async move {
|
|
initialize_app(&mut app);
|
|
|
|
set_local_onboarding_completed(&mut app, true);
|
|
app.update(|ctx| {
|
|
// User::test() defaults to is_onboarded = true; assert that and
|
|
// leave it in place.
|
|
assert_eq!(
|
|
AuthStateProvider::as_ref(ctx).get().is_onboarded(),
|
|
Some(true)
|
|
);
|
|
});
|
|
|
|
app.update(|ctx| {
|
|
let auth_state = AuthStateProvider::as_ref(ctx).get().clone();
|
|
RootView::sync_local_onboarding_to_server(&auth_state, ctx);
|
|
});
|
|
|
|
app.read(|ctx| {
|
|
assert_eq!(
|
|
AuthStateProvider::as_ref(ctx).get().is_onboarded(),
|
|
Some(true)
|
|
);
|
|
});
|
|
});
|
|
}
|