Misc · Terms and notices: tests for every way out; switch labels wrap

Tests now press Decline and the scrim, see focus return to the opener
after Accept, see necessary cookies stay on and off the Tab path, and
see the license list mark its row and read each version and license.
lists::ListItem marks its description and selected state for tests.
forms::Switch's label wraps in its own block, as Checkbox's does.
Ely's own row in the gallery shows both of its license texts.
This commit is contained in:
ZacharyZhang-NY committed 2026-09-28 04:09:49 -04:00
1 parent 2837c802b5
commit 8794a42d42
7 files changed
+123 -24

No files matched your search

+14 -8
View File
@@ -1,7 +1,8 @@
use std::rc::Rc;
use gpui::{
App, ElementId, IntoElement, ParentElement, RenderOnce, SharedString, Styled, Window, div,
App, ElementId, InteractiveElement, IntoElement, ParentElement, RenderOnce, SharedString,
Styled, Window, div,
};
use crate::{
@@ -104,13 +105,18 @@ impl RenderOnce for CookieBanner {
.flex()
.flex_col()
.gap_3()
.child(row(
Switch::new((id.clone(), "necessary"), true)
.label("Necessary")
.disabled(true),
"Keeps the site working; always on.".into(),
cx,
))
.child({
let (on, rests) = (true, true);
div()
.debug_selector(|| format!("cookie-necessary-{on}-{rests}"))
.child(row(
Switch::new((id.clone(), "necessary"), on)
.label("Necessary")
.disabled(rests),
"Keeps the site working; always on.".into(),
cx,
))
})
.children(rows)
});
let (all, none, saved) = (answer.clone(), answer.clone(), answer);
+86 -9
View File
@@ -1,9 +1,13 @@
use std::cell::{Cell, RefCell};
use gpui::{AnyElement, IntoElement, TestAppContext};
use gpui::{
AnyElement, App, Context, FocusHandle, IntoElement, Modifiers, ParentElement, Render, Styled,
TestAppContext, Window, div, point, px,
};
use super::{at_root, press, shown, stage};
use super::{at_root, press, settle, shown, stage};
use crate::misc::{ConsentDialog, CookieBanner, LicenseViewer, Package};
use crate::{buttons::Button, primitives::FocusScope, theme::Theme};
thread_local! {
static SAID: RefCell<Vec<String>> = const { RefCell::new(Vec::new()) };
@@ -24,20 +28,25 @@ fn licenses() -> AnyElement {
[
Package::new("Alpha", "1.0", "MIT", "Permission is hereby granted"),
Package::new("Beta", "2.3", "ISC", "Permission to use, copy, modify"),
Package::new("Gamma", "0.9", "OFL-1.1", "Permission is hereby granted"),
],
)
.into_any_element()
}
/// The first package's license shows; a move down the list shows the next one's.
/// Each row reads its version and license; the first license shows, and moves down the list show the next ones, the list marking each.
#[gpui::test]
fn a_license_viewer_shows_the_chosen_license(cx: &mut TestAppContext) {
let (_, cx) = stage(licenses, cx);
assert!(shown("license-Alpha", cx));
assert!(shown("license-Alpha", cx) && shown("item-description-2.3 · ISC", cx));
press("tab", cx);
press("down", cx);
press("space", cx);
assert!(shown("license-Beta", cx));
assert!(shown("license-Beta", cx) && shown("item-selected-Beta", cx));
press("down", cx);
assert!(
shown("license-Gamma", cx),
"the list kept its mark on Beta, so its cursor went on from there"
);
}
fn consent() -> AnyElement {
@@ -78,13 +87,77 @@ fn consent_waits_for_the_box(cx: &mut TestAppContext) {
assert_eq!(said(), ["accepted"], "Accept answers alone");
}
/// Escape declines, once.
/// Escape, Decline and a press on the scrim each decline, once.
#[gpui::test]
fn escape_declines_consent(cx: &mut TestAppContext) {
fn every_other_way_out_declines(cx: &mut TestAppContext) {
let (_, cx) = stage(consent, cx);
press("tab", cx);
press("escape", cx);
assert_eq!(said(), ["declined"]);
OPEN.set(true);
cx.update(|window, _| window.refresh());
settle(cx);
press("tab", cx);
press("tab", cx);
press("enter", cx);
OPEN.set(true);
cx.update(|window, _| window.refresh());
settle(cx);
cx.simulate_click(point(px(3.0), px(3.0)), Modifiers::none());
settle(cx);
assert_eq!(said(), ["declined", "declined", "declined"]);
}
/// A page with a button that opens the consent dialog, which answers into `said`.
struct Opener {
root: FocusHandle,
button: FocusHandle,
}
impl Render for Opener {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let view = cx.entity();
FocusScope::new(&self.root)
.root()
.size_full()
.child(
Button::new("open", "Terms")
.focus_handle(&self.button)
.on_click(move |_, _, cx| {
OPEN.set(true);
view.update(cx, |_, cx| cx.notify());
}),
)
.child(div().child(consent()))
}
}
/// Accept hands focus back to the button that opened the terms.
#[gpui::test]
fn consent_hands_focus_back_to_its_opener(cx: &mut TestAppContext) {
OPEN.set(false);
cx.update(|cx: &mut App| {
Theme::init(cx);
crate::forms::bind_keys(cx);
cx.bind_keys([
gpui::KeyBinding::new("tab", crate::primitives::FocusNext, None),
gpui::KeyBinding::new("shift-tab", crate::primitives::FocusPrev, None),
]);
});
let (view, cx) = cx.add_window_view(|_, cx| Opener {
root: cx.focus_handle(),
button: cx.focus_handle(),
});
let button = view.read_with(cx, |opener, _| opener.button.clone());
cx.update(|window, _| window.focus(&button));
settle(cx);
press("enter", cx);
press("tab", cx);
press("space", cx);
press("tab", cx);
press("tab", cx);
press("enter", cx);
assert_eq!(said(), ["accepted"]);
assert!(cx.update(|window, _| button.is_focused(window)));
}
fn cookies() -> AnyElement {
@@ -106,6 +179,10 @@ fn a_cookie_banner_hands_over_the_kinds_chosen(cx: &mut TestAppContext) {
press("tab", cx);
press("enter", cx);
assert!(!at_root(cx), "Save choices took Choose's focus");
assert!(
shown("cookie-necessary-true-true", cx),
"necessary cookies stay on"
);
for _ in 0..3 {
press("shift-tab", cx);
}