Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
use warp_core::user_preferences::GetUserPreferences as _;
|
||||
use warpui::{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)
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user