main
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f7363e98af |
Show the grant form's supersession hint only once a marked product is chosen
Task 5.10 of #269's change. The Issue grant form showed a yellow alert under its lead whenever its Product select offered a product marked with the warning sign, before anything was chosen, so it read as a standing warning. The sentence now reads "This grant would supersede a tier a subscription pays for; its billing pauses until the grant ends." and is the Product field's one hint line, hidden until the operator chooses a marked product and hidden again when an unmarked one is chosen. A refused submission that chose a marked product renders it shown. The form's message is the lead alone. The forms library gains the mechanism, for any Stacked form: a select declares HintOnChoice with its Hint, options carry ShowsHint, and the field part renders the hint only when an offered option shows it, hidden unless the chosen one does, and named by the select's aria-describedby only while it shows. One external script, hint-on-choice.js, loaded with defer by the operator shell, follows later choices and htmx swaps through data-hint-toggle and data-shows-hint. The invariants refuse HintOnChoice off a Stacked select, without a Hint or with a Notice, and the escape hatch refuses data-hint-toggle. The change's text gains a form-library requirement ("A select's hint can wait for the option that shows it") and modifies form-conventions' "Every control has a label, and its hint and error are described" so a hint is described while it shows. docs/design-system.md describes the mechanism in section 8 and adds the script to the progressive-enhancement table. Tests: TestOrgEnrollmentIssueGrantSupersedeHint (at rest, no marked product, a refused submission with a marked, an unmarked and no product, the message the lead alone), TestOperatorShellLoadsTheHintToggle, TestRenderHintOnChoiceFollowsTheChosenOption, TestInvariantsHintOnChoiceBelongsToAStackedSelectWithItsHint, the escape hatch's and the invariant messages' rows, and TestGrantSupersedeHintWalkthrough, which chooses a marked and then an unmarked product on the demo's Carlos Member organization and checks the hint and aria-describedby both ways. Three organization goldens change only in the message and the Product field. Review: round 1, three majors (the hint supplied per render, bypassing the registry's hint checks; no spec for the library's new contract, with form-conventions saying the opposite; the script's break unreachable while the app serves its embedded copy) and five minors, all fixed; round 2, no major. Breaks: 12 of 12 caught. 8 in code; the script's 4 run as a second list whose preparation rebuilds and restarts the app on the broken tree. Full suite on reset databases: 4843 pass, 14 skip. make screens: Carlos Member's organization, open and refused, at both widths, loses the alert. Hand captures of the form at rest, with a marked product chosen and with an unmarked one chosen after it sit beside the change's screens. |
||
|
|
e5ab7da9d0 |
Drop the filler phrases from five member-facing sentences
Five sentences a member can read carried a phrase the copy rule
refuses. They now read:
The form could not be read. Try again. (a form body, and a batch
body, that cannot be read)
That name isn't available. Choose another.
... Another can start there after %s. ... (abandonment budget)
... Another can start after %s. (initiation budget)
They were "Please try again." (twice), "Please choose another." and
"You can start another ..." (twice). The lint does not read
internal/forms or internal/domains, so it never saw them; its reach is
unchanged. The sentences in workflow results and FedWiki's sync errors
are untouched.
The two "malformed body" rows of
internal/forms/testdata/parse-answers.golden carry the new sentence;
no other golden changes. The new TestMemberMessageWording pins the
three domain sentences word for word; no test pinned them before. It
failed at the parent and passes at this commit.
How it was shown to change no other output: the names and results of
./internal/forms, ./internal/domains, ./internal/server and
./internal/integrations/fedwiki/web (on freshly reset test databases)
are equal at the parent and at this commit apart from the added test,
which fails at the parent. Five breaks, each restoring one old
sentence, are caught: three by TestMemberMessageWording, two by
TestParseAnswers.
Not probed: that no screen shows these sentences. The new tests read
the strings and the parse golden; no browser run was taken for this
commit.
|
||
|
|
46a7cbbf11 |
Characterize what Parse answers for each control
TestParseAnswers posts 38 one-field forms (a row with a ShowIf adds the field it reads) and one batch whose body cannot be read, and prints for each row the form error, the refusals by key in sorted order, and the raw value, presence and typed answers (bool, int, time, UUID). The text is compared through golden.Compare with testdata/parse-answers.golden (99 lines). The rows cover date and datetime ranges, the datetime-local layout, a Min or Max that does not parse (read as no bound), a pattern that does not compile, the "expected format" fallback, a UUID typed from a select and from a hidden field, "an" before a vowel, both "could not be read" form errors, MaxLen counted in runes, the optional and the required radio, a deliberate empty option, a checkbox with another value, a repeated name and a pattern read twice. Shown to change no output: only a test file and a golden are added. The names and results of ./internal/forms ./internal/server ./internal/integrations/... (2112 at the parent and 2113 at the commit, reset test databases before each run) differ only by the new TestParseAnswers. The golden is byte-equal to the output of the stand-alone program that prints the same rows from the unchanged library. The new test passes five runs in a row. 11 breaks, each edited once in internal/forms/parse.go and each caught by the new test, which fails with the golden differing from what the code produced. The old side has no counterpart: every break is a new-side record, since no old test names this one. None dropped. Pinned defects, so a later fix flips them by name: both "could not be read" sentences (the form's and the batch's) carry "Please", a filler phrase the copy rule refuses; the lint does not read internal/forms. Not probed: the rows parse_test.go already pins (required and trimmed text, optional empty text, MaxLen, number range and "whole number", select outside the options and empty, optional and required radio, runtime options, checkbox absence, repeated names, the pattern's hint, date parsing and "not a valid date", ShowIf). The breaks probe mostly rows only this test pins; one break per pinned row would repeat a kind already measured. The break that lets an optional radio group stay empty is also caught by TestParseRequiredRadioNeedsAChoice. Four rows only this test pins have no break: the "later than this form allows" message, a malformed Max, a date bound that does not parse, and a checkbox submitted with a value other than its own; each is the same kind as a probed literal or bound. |
||
|
|
08e22939d7 |
Table every message the form invariants give
TestInvariantMessages runs CheckInvariants over 73 declarations, each
one of four well-formed bases (stacked, batch, table, dense) with one
change, and prints every case's problems whole, in the order
CheckInvariants returns them. The text is compared through
golden.Compare with testdata/invariant-messages.golden (156 lines, 59
distinct messages).
The cases cover 59 of the 61 messages, the four bases and a confirm
form with no fields (no problem), the inputs on which the registry and
the lint read an em dash differently ("1 — 2" and a lone "—", both
refused here), the strings the registry does not check today (a column
heading, a static row's Value, a filler phrase in a hint: no problem),
and one declaration with a problem in each rule group, whose eight
problems come out in the groups' order. The two dashed strings of one
field come out in either order at this commit, because the dash checks
range over a map, so that case sorts its problems and says why.
Deletes internal/forms' TestRegisteredFormsSatisfyTheInvariants: no form
registers in that test binary, so it checked nothing. The test of the
same name in internal/server, which runs over every registered form,
stays.
Shown to change no output: only test files and a golden change. The
names and results of ./internal/forms ./internal/server
./internal/integrations/... (2112 results each), taken with the test
database reset and the app down at the parent and at this commit, are
equal apart from the new TestInvariantMessages and the deleted
TestRegisteredFormsSatisfyTheInvariants in internal/forms. The new test
passes five runs in a row.
15 breaks, each edited once in internal/forms/invariants.go and each
caught by the new test, which fails with the golden differing from what
the code produced. The old side has no counterpart: every break is a
new-side record, since no old test names this one. None dropped.
Pinned defects, so a later fix flips them by name: the registry refuses
any em dash where the lint exempts a lone marker and a dash with no
letter beside it; the registry does not check a column heading, a static
row's Value or a filler phrase; the hint cap counts bytes and its
message prints them as characters (no row is non-ASCII, so the golden
shows the count only); two dashed strings in one field come out in
either order.
Not probed: the words of the 46 messages no break changes, since each is
a literal the golden prints whole and a break per message would repeat
the reworded-message breaks' kind; and two messages no declaration
reaches, "escape hatch carries %q, which the part owns" (a key reaches
it only after the data-/hx- prefix test, and no owned key has either
prefix) and "steps wider than a half, which would reach a full row" (the
ladder refuses a wider step only from the half rung, and no control
stands on it today).
|