Skip to content

Conversation

@choonkeat
Copy link
Owner

@choonkeat choonkeat commented Dec 18, 2025

This PR adds runtime validation for ChooseMultiple fields with System presence, completing the fix started in PR #54. It implements "Layer 2" defense (runtime validation) to complement PR #54's "Layer 1" (editor prevention).

Builds on: PR #54 & related to #4

Problem: System + ChooseMultiple fields with no explicit minRequired allowed 0 selections in CollectData mode, causing backend validation to fail despite appearing valid in the UI.

Solution:

  1. Create validation element with min="1" when presence == System and minRequired == Nothing
  2. Attach event handlers to track selections for System fields
  3. Add comprehensive E2E tests

Commits

Setup & Formatting

Core Implementation

  • 4c46d12 - fix: enforce System presence as minRequired=1 for ChooseMultiple
  • 2427a54 - fix: attach event handlers for System + ChooseMultiple validation

Documentation & Tooling

  • 1a54817 - docs: update implementation tracking file with final status
  • a619337 - docs: update tracking file with complete implementation details
  • 0e7bd5d - fix: add elm-format to generate-elm-test-json target

wynn and others added 9 commits December 18, 2025 11:21
- Test verifies validation element should be created for System fields
- Currently needs refinement to properly interact with Elm app
- Will verify fix manually for now
- Add effectiveMin logic in validation element generation
- When presence is System and minRequired is Nothing, treat as Just 1
- Creates validation element with min="1" for System fields
- Aligns frontend validation with backend Go validation expectations
- Fixes bug where System + ChooseMultiple fields allowed 0 selections
- Modified isChooseManyUsingMinMax to also check for System presence
- System presence fields now get event handlers to track selections
- Validation element value updates correctly when checkboxes are clicked
- Added working E2E tests that verify the complete fix
- Tests pass in Chrome, Firefox, and WebKit
Ensures generated tests/GoElmCrossValidationTestData.elm is properly formatted
after generation, preventing formatting changes in git diff
@netlify
Copy link

netlify bot commented Dec 18, 2025

Deploy Preview for tiny-form-fields ready!

Name Link
🔨 Latest commit e452953
🔍 Latest deploy log https://app.netlify.com/projects/tiny-form-fields/deploys/694426321712d20008d3531d
😎 Deploy Preview https://deploy-preview-55--tiny-form-fields.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment on lines +2293 to 2316
let
-- System presence implies minRequired = 1 if not explicitly set
effectiveMin =
case ( formField.presence, minRequired ) of
( System, Nothing ) ->
Just 1

_ ->
minRequired

-- Need validation if we have constraints
needsValidation =
effectiveMin /= Nothing || maxAllowed /= Nothing
in
-- Only apply validation in CollectData mode, not in Editor mode
if not disabledMode && (minRequired /= Nothing || maxAllowed /= Nothing) then
if not disabledMode && needsValidation then
[ input
[ type_ "number"
, required True
, attribute "value" (String.fromInt selectedCount) -- raw value for browser only
, attribute "min" (Maybe.map String.fromInt minRequired |> Maybe.withDefault "")
, attribute "min" (Maybe.map String.fromInt effectiveMin |> Maybe.withDefault "")
, attribute "max" (Maybe.map String.fromInt maxAllowed |> Maybe.withDefault "")
, attribute "class" "tff-visually-hidden"
]
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When presence == System and minRequired == Nothing, we treat it as minRequired == Just 1. This aligns frontend validation with backend expectations (Go's isRequired() returns true for System presence).

Without this, the validation element wouldn't be created at all, allowing invalid form submission that would fail backend validation.

-- Need event handlers if:
-- 1. Has explicit min/max constraints, OR
-- 2. System presence (implies min=1 requirement)
minRequired /= Nothing || maxAllowed /= Nothing || formField.presence == System
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added || formField.presence == System to ensure event handlers are attached for System fields. This allows the validation element's value attribute to be updated as checkboxes are clicked.

Without event handlers, the validation element would always show value="0" even when checkboxes are selected, because Elm wouldn't track the selection changes. The hidden <input type="number" min="1" value="0"> would pass browser validation incorrectly.

@echo "Generating cross-validation test data..."
node scripts/generate-cross-validation-tests.js
@echo "Formatting generated Elm test data..."
npx elm-format tests/GoElmCrossValidationTestData.elm --yes
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added automatic formatting after test generation to keep git history clean.

The Node.js generator doesn't produce properly formatted Elm code. Without this, every make test-json-compatibility would create formatting-only diffs.

Add PLAYWRIGHT_ARGS variable to control Playwright reporter output:
- Local dev: defaults to --reporter=line for fast output
- CI: override with PLAYWRIGHT_ARGS="" to use HTML reporter from config

Update GitHub Actions workflow:
- Upload playwright-report only on test failure
- Add if-no-files-found: ignore to suppress warning when tests pass
- Pass PLAYWRIGHT_ARGS="" to enable HTML reporter for debugging failures

Fixes "No files were found with the provided path: playwright-report/" warning
@choonkeat choonkeat merged commit 649b9af into main Dec 18, 2025
7 of 8 checks passed
@choonkeat choonkeat deleted the fix-multiplechoice-system-minrequired-0 branch December 18, 2025 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants