Skip to content

TST-50: Stress the boundaries — property-based and adversarial input tests #717

@Chris0Jeky

Description

@Chris0Jeky

Context

Existing fuzz tests cover starter-pack manifests, LLM intent classification, and export/import contracts. This issue expands adversarial input testing to more system boundaries — the places where user input enters the system and where the system must not break regardless of what it receives.

Candidate Surfaces for Property-Based / Fuzz Testing

Backend

API Request Bodies (adversarial JSON)

  1. Card creation: Random strings for title (0 to 100K chars), description (nulls, unicode, control chars, script tags), position (negative, float, MAX_INT)
  2. Board creation: Name with every unicode block, duplicate names, SQL injection attempts in name
  3. Capture text: Random binary data, null bytes, very long strings, nested JSON in text field
  4. Proposal operations JSON: Malformed operation types, missing fields, extra unknown fields, deeply nested objects
  5. Webhook URL: every RFC 3986 edge case, URL with authentication credentials, URL with fragments, data: URLs, javascript: URLs

Domain Entity Construction

  1. Property: for any valid construction parameters, the entity should be constructable and its invariants hold
  2. Property: for any invalid parameter combination, DomainException is thrown (never silently accepts bad data)
  3. Property: for any valid entity, calling Touch() changes UpdatedAt

JSON Serialization Round-Trip

  1. Property: for any board state (random cards, columns, labels), serialize → deserialize produces identical state
  2. Property: for any capture payload, SerializePayload → ParsePayload is identity
  3. Property: for any CaptureRequestContract.WithProvenance payload, the provenance fields are always recoverable

SQLite Query Boundary Values

  1. GUID format: verify queries work with uppercase, lowercase, and mixed-case GUIDs
  2. DateTime boundary: epoch, year 9999, DateTime.MinValue, DateTime.MaxValue
  3. String length: empty string vs null vs whitespace-only vs max-length

Frontend

Input Sanitization

  1. Card title input: paste 10K chars → verify truncation or rejection, no crash
  2. Search query: paste SQL injection / XSS payloads → verify sanitized in display
  3. Chat input: very long message → verify sent or truncated, no freeze
  4. Board name: HTML entities in name → displayed as text, not rendered as HTML

State Store Resilience

  1. Property: for any sequence of store actions (create, update, delete, refresh), the store ends in a consistent state
  2. Property: for any API error response, the store handles it without throwing an unhandled exception

Implementation Notes

Backend

  • Use FsCheck or manual random generators for C# property tests
  • Existing fuzz pattern in `Taskdeck.Application.Tests/Fuzz/` can be extended
  • For API-level fuzzing: send random JSON bodies to endpoints, verify response is always valid `ApiErrorResponse` (never 500 with stack trace)
  • Consider a "no 500s" meta-test: for any well-formed request with random content, the API never returns 500

Frontend

  • Use fast-check for JavaScript property-based testing
  • Focus on components that render user-provided content: card titles, descriptions, chat messages

Success Criteria

  • No 500 Internal Server Error from any random input
  • No unhandled exceptions in frontend from any random input
  • No data corruption from any random input sequence
  • All error responses have valid `ApiErrorResponse` shape

Considerations

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Review

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions