Issue #3614039: Add FunctionalJavascript coverage for the booking calendar and place map
What this adds
BookingCalendarTest, yoyaku_calendar's first browser test: 11 tests over
calendar.js, which had none. Completes #3614039, whose place-map half merged as
52deed1.
Plus one production fix the tests found, below.
The bug the tests found
The calendar block's config schema was keyed block.settings.yoyaku_calendar_block
while the block plugin id is yoyaku_calendar. The settings therefore had no
schema at all: harmless-looking in production, but the block's resource setting
went unchecked, and any test that places the block dies on
settings.resource missing schema from core's schema checker. All 11 tests errored
on that before anything else ran. Fixed by keying it to the plugin id, and
resource is nullable: true because defaultConfiguration() returns NULL.
What the tests pin
The anchor is #3612171, the one bug this file has already cost: a visitor holding
the last place of a day was shown that day as full and locked out of their own
booking. The feed is cached for everyone so it reports the day as full; the
visitor's own holds arrive separately in a cookie, and applyHeld() has to add
them back before anything decides what is bookable. Two tests cover it: the held
day stays open to its holder, and an overlay past its deadline colors nothing.
The rest, in value order:
- the grid draws from the fetched feed, with an open day clickable, a full day visible but inert, and a day with no slot drawn rather than omitted;
- a feed that cannot be read says so instead of leaving a box that
once()has already claimed. Provoked the way a site actually breaks, with a visitor who may reach the page but not the availability route, so it needs no test module; - a picked day and its quantity survive month navigation, which the file's own docblock claims and nothing checked;
- the hidden field carries
{"categories": {"<target>": qty}}, asserted as parsed JSON because that is the whole contract withCalendarBookingForm::submitForm(); - a quantity is what opens the submit, and taking it away shuts it again;
- a contiguous resource refuses non-consecutive days and says why;
- a single-day resource replaces the chosen day rather than adding to it;
- removing a line from the summary clears what it asked for;
- the calendar opens on the first month that has slots, the seam between
firstSlotMonth()on the server andstartMonthin the JS.
Two things worth knowing before touching this class
The fixture cannot be pinned to a distant year. AvailabilityController
clamps ?month to WINDOW_MONTHS (24) either side of now and falls back to the
current month outside it, so slots seeded in 2030 are answered with the current
month's availability and the grid draws empty. Every day is anchored on the first
of next month instead. This cost a debugging round; the reason is in the property's
docblock.
A full day carries no data-date. renderGrid() sets that attribute only on a
day it will let you click, so a selector keyed on it silently matches nothing for a
sold-out day, and assertions about one error instead of failing. The day() helper
looks the cell up by position.
Deliberately out of scope
Prices and the selection total. They arrive through yoyaku_payment's optional resolver, so asserting a total means installing the whole payment stack for every test in the class. They belong in their own class, the same split the place-map tests made.
The check-in scanner too: it drives a camera through getUserMedia, and a flaky
test that later gets disabled is worse than none.
Verification
11 tests, 90 assertions, run twice against chromedriver. phpcs clean over the whole
module with --standard=Drupal,DrupalPractice (the repo-local config excludes
contrib and inspects nothing, so it is not the check it looks like), and cspell
clean with the project dictionary. No new translatable strings and no JS change, so
fr.po is untouched.
A mismatch found but not fixed here
firstSlotMonth() is not clamped, so a resource whose first slot is more than 24
months out hands the JS a startMonth the feed will refuse, and the visitor gets an
empty grid with nothing said. 24 months covers any realistic horizon, so this is
unlikely rather than urgent, and it is a behavior change rather than test coverage.
Worth its own issue.