fix(blur): the heid code-review and bug-hunt panels on r2b merge 1, folded

Both panels ran 4/4 on 5ded5ff. They converged on the board and doc-page
gaps independently.

- A board holding files lost both blur controls (they sat inside the
  board suppression meant for the one-click wipe), while its items'
  "◉ booth" labels pointed at them. Only the wipe is board-suppressed now.
- A blurred doc's own full page rendered clear. Its body is blurred there
  too, with its own reveal and a Reveal all to put the blur back.
- set_booth_blurred followed a planted .blurbooth symlink (`touch`), and
  the new control made that a click away. Anything at the name already
  reads as fogged; otherwise it is created O_CREAT|O_EXCL|O_NOFOLLOW.
- The fog landing echoed `back` unchecked into the 303. It is now built
  from the review ring, as the mark routes do.
- The fog form is its own region, so an in-place save refreshes its
  label. Reveal all stays outside every region: its state lives in the
  tab.
- The review's Space-to-advance no longer swallows Space on a focused
  button or link.
- Top-bar controls stay on one line at phone width.
- Tests tightened:
  - method="post" on the fog forms;
  - exact blur values;
  - a storage READ that throws;
  - an item's own reveal carried across a swap;
  - reveal gated where it can act.

r2b.toml: 26/26 proved. 774 passed.
This commit is contained in:
vh
2026-09-23 18:41:32 -07:00
parent 5ded5ffe55
commit 75623c7dbc
9 changed files with 405 additions and 30 deletions
+93 -4
View File
@@ -618,8 +618,8 @@ def test_reveal_all_on_booth_a_does_not_reveal_booth_b_or_the_desk(browser, live
desk = page.evaluate("""() => [...document.querySelectorAll('.desk-strip img.blurred-thumb')]
.map(i => getComputedStyle(i).filter)""")
page.close()
assert "blur" in b_tile, b_tile
assert desk and all("blur" in f for f in desk), desk
assert b_tile == "blur(22px)", b_tile
assert desk and all(f == "blur(16px)" for f in desk), desk # exact: blur(0px) is not blurred
def test_reveal_all_survives_an_in_place_save(browser, live):
@@ -676,11 +676,100 @@ def test_reveal_all_never_shows_without_js_and_a_storage_failure_still_applies_t
nojs = page.locator("[data-reveal-all]").is_visible()
ctx.close()
page = browser.new_page(viewport={"width": 1400, "height": 900})
page.add_init_script("Storage.prototype.setItem = function () { throw new Error('quota'); };")
errors = []
page.on("pageerror", lambda e: errors.append(str(e)))
# READS and WRITES both throw: the pre-paint read must degrade to "not
# revealed" without raising, and the click must still apply.
page.add_init_script("""Storage.prototype.setItem = function () { throw new Error('quota'); };
Storage.prototype.getItem = function () { throw new Error('denied'); };""")
page.goto(f"{base}/b/g/", wait_until="networkidle")
_settle(page)
before = page.evaluate(_FILTER, 'figure.item[data-item="a.png"] img')
page.locator("[data-reveal-all]").click()
_settle(page)
lifted = page.evaluate(_FILTER, 'figure.item[data-item="a.png"] img')
page.close()
assert not nojs
assert lifted == "none", lifted
assert before == "blur(22px)" and lifted == "none", (before, lifted)
assert errors == [], errors
def test_an_items_own_reveal_survives_an_in_place_save(browser, live):
"""heid code-review (groa, kimi): nothing pinned the swap carrying an item's
own `revealed` — deleting it from the carry list left every test green.
Reveal one tile, save something else in place: it stays revealed, and its
button still says so."""
base, root = live
_blurred_set(root, blur=("a.png", "b.png"), flag=())
page = browser.new_page(viewport={"width": 1400, "height": 900})
page.goto(f"{base}/b/g/", wait_until="networkidle")
page.locator('figure.item[data-item="b.png"] .reveal').click()
page.locator('figure.item[data-item="a.png"] .flagtoggle button').click()
page.wait_for_selector('figure.item.is-flagged[data-item="a.png"]', timeout=10000)
_settle(page)
got = [page.evaluate(_FILTER, 'figure.item[data-item="b.png"] img'),
page.locator('figure.item[data-item="b.png"] .reveal').inner_text()]
page.close()
assert got[0] == "none" and "hide" in got[1], got
def test_reveal_all_lifts_a_blurred_docs_own_page(browser, live):
"""The doc page's blur (heid code-review) obeys the same <html> class, and
its own reveal works."""
from booth.app import set_blurred
base, root = live
b = root / "g"
b.mkdir()
(b / "n.md").write_text("# secret\n\nbody")
set_blurred(b, "n.md", True)
page = browser.new_page(viewport={"width": 1200, "height": 800})
page.goto(f"{base}/b/g/view?f=n.md", wait_until="networkidle")
_settle(page)
at_rest = page.evaluate(_FILTER, "#docbody .markdown-body, #docbody .textview")
page.locator("#docreveal").click()
_settle(page)
own = page.evaluate(_FILTER, "#docbody .markdown-body, #docbody .textview")
page.close()
assert at_rest == "blur(22px)" and own == "none", (at_rest, own)
def test_space_on_a_focused_review_button_presses_it_and_does_not_move_on(browser, live):
"""heid bug-hunt (hulda): the review's document-level Space handler moved to
the next item before a focused button could take the key, so a keyboard
user could not press Reveal all or the fog control with Space."""
base, root = live
_blurred_set(root, flag=())
page = browser.new_page(viewport={"width": 1400, "height": 900})
page.goto(f"{base}/b/g/view?f=a.png", wait_until="networkidle")
page.locator("[data-reveal-all]").focus()
page.keyboard.press(" ")
_settle(page)
got = [page.url, page.evaluate("document.documentElement.classList.contains('reveal-all')")]
page.close()
assert got[0].endswith("/b/g/view?f=a.png") and got[1], got
def test_the_review_and_doc_top_bars_fit_a_phone(browser, live):
"""heid bug-hunt (hulda, groa; needs-repro): the top bar gained the fog
control and Reveal all beside the name, the fit toggle and the download.
At 390px no review or doc page scrolls sideways, even with a long name."""
from booth.app import set_blurred
base, root = live
b = _blurred_set(root, flag=())
long = "a-rather-long-picture-name-" * 3 + ".png"
(b / long).write_bytes(PNG)
set_blurred(b, long, True)
(b / "n.md").write_text("# n")
set_blurred(b, "n.md", True)
over = {}
for url in (f"/b/g/view?f={long}", "/b/g/view?f=n.md"):
page = browser.new_page(viewport={"width": 390, "height": 844})
page.goto(f"{base}{url}", wait_until="networkidle")
over[url] = page.evaluate(
"document.documentElement.scrollWidth - document.documentElement.clientWidth")
# and nothing squeezed into a stack: every top-bar control is one line
over[url + " tallest"] = page.evaluate("""() => Math.max(...[...document.querySelectorAll(
'.vbar button, .vbar .vbtn')].filter(e => e.offsetParent).map(e => e.getBoundingClientRect().height)) - 40""")
page.close()
assert all(v <= 0 for v in over.values()), over