test(#280): integration test for full Discord delivery pipeline (#234 + #270/#271/#272/#273) #283

Merged
Mark merged 8 commits from wt/integration-verify into master 2026-08-20 10:14:20 +00:00
Owner

Summary

Drives a synthetic MeshIntentResult payload through DiscordBotService._run_intent for each of the four canonical result shapes, exercising the full end-to-end pipeline:

typing indicator (open) -> run intent (poll loop) -> render embed (or plain text)
  -> split() if > 2000 chars -> attach file if > attachment_threshold -> typing (close)

The test confirms every sibling component landed in its deliverable shape:

  • #270 splitter — split() is invoked inside the chat formatter; long prose produces multiple ResponseParts, each at or below Discord's 2000-char message limit; nested code-fence integrity is preserved across the split stream.
  • #271 embed builder — EmbedBuilder is exercised via the typed MeshIntentResult path; IntentType.RESEARCH produces a research embed with title/description/fields/footer/color within the 6000-char total budget.
  • #272 progress indicator — async with progress(channel, intent_id) opens the typing context manager before the poll loop and exits cleanly on completion or error.
  • #273 attachment handler — attachment_threshold triggers _format_chat_attachment; a discord.File is uploaded and a summary message references the attachment.

Test scenarios

Scenario Shape tested
test_short_chat_response_* short
test_long_prose_response_* long prose (split)
test_response_with_code_blocks_* with code blocks (fences)
test_oversized_response_is_* with file (attachment)
test_research_intent_runs_full_* full pipeline + embed

Plus four TestComponentsPresent.* tests that import each component directly from runtime to prove they're package-exported and individually usable.

Verification

  • pytest tests/unit/test_delivery_pipeline_integration.py -> 9 passed in 0.25s
  • pytest tests/unit/{test_delivery_pipeline_integration,test_discord_response,test_discord_commands,test_discord_progress,test_embed_builder_intents,test_discord_bot}.py -> 136/136 passed
  • ruff check tests/unit/test_delivery_pipeline_integration.py -> clean
  • black tests/unit/test_delivery_pipeline_integration.py -> formatted
  • Pre-commit hooks all passed

References

  • Forgejo #280 (this work)
  • #234 (base response delivery formatter, closed)
  • #270 (splitter delta, closed)
  • #271 (embed builder delta, closed)
  • #272 (progress indicator + bot wiring, closed)
  • #273 (attachment handler delta, closed)

Kanban

Closes t_b702138a (verifier integration verification).

## Summary Drives a synthetic `MeshIntentResult` payload through `DiscordBotService._run_intent` for each of the four canonical result shapes, exercising the full end-to-end pipeline: ``` typing indicator (open) -> run intent (poll loop) -> render embed (or plain text) -> split() if > 2000 chars -> attach file if > attachment_threshold -> typing (close) ``` The test confirms every sibling component landed in its deliverable shape: - **#270 splitter** — `split()` is invoked inside the chat formatter; long prose produces multiple `ResponsePart`s, each at or below Discord's 2000-char message limit; nested code-fence integrity is preserved across the split stream. - **#271 embed builder** — `EmbedBuilder` is exercised via the typed `MeshIntentResult` path; `IntentType.RESEARCH` produces a research embed with title/description/fields/footer/color within the 6000-char total budget. - **#272 progress indicator** — `async with progress(channel, intent_id)` opens the typing context manager before the poll loop and exits cleanly on completion or error. - **#273 attachment handler** — `attachment_threshold` triggers `_format_chat_attachment`; a `discord.File` is uploaded and a summary message references the attachment. ## Test scenarios | Scenario | Shape tested | | ------------------------------------- | ------------------------- | | `test_short_chat_response_*` | short | | `test_long_prose_response_*` | long prose (split) | | `test_response_with_code_blocks_*` | with code blocks (fences) | | `test_oversized_response_is_*` | with file (attachment) | | `test_research_intent_runs_full_*` | full pipeline + embed | Plus four `TestComponentsPresent.*` tests that import each component directly from `runtime` to prove they're package-exported and individually usable. ## Verification - `pytest tests/unit/test_delivery_pipeline_integration.py` -> **9 passed in 0.25s** - `pytest tests/unit/{test_delivery_pipeline_integration,test_discord_response,test_discord_commands,test_discord_progress,test_embed_builder_intents,test_discord_bot}.py` -> **136/136 passed** - `ruff check tests/unit/test_delivery_pipeline_integration.py` -> clean - `black tests/unit/test_delivery_pipeline_integration.py` -> formatted - Pre-commit hooks all passed ## References - Forgejo #280 (this work) - #234 (base response delivery formatter, closed) - #270 (splitter delta, closed) - #271 (embed builder delta, closed) - #272 (progress indicator + bot wiring, closed) - #273 (attachment handler delta, closed) ## Kanban Closes `t_b702138a` (verifier integration verification).
test(#280): integration test for full Discord delivery pipeline (#234 + #270/#271/#272/#273)
Some checks failed
CI / Lint and Format (pull_request) Has been cancelled
CI / Type Check (pull_request) Has been cancelled
CI / Security Check (pull_request) Has been cancelled
CI / Code Quality Checks (pull_request) Has been cancelled
CI / Unit Tests (pull_request) Has been cancelled
CI / Integration Tests (pull_request) Has been cancelled
CI / Smoke Tests (pull_request) Has been cancelled
CI / Full Test Suite (pull_request) Has been cancelled
f9a130fbba
Drives a synthetic MeshIntentResult payload through DiscordBotService._run_intent
for each of the four canonical result shapes: short, long prose, code blocks,
and with file. Plus a research-intent scenario exercising every component.

Refs: #234, #270, #271, #272, #273, #280
Kanban: closes t_b702138a (verifier integration verification).
test(#280): extract shared attachment constants into tests/unit/_constants.py (sourced from #273 allowlist rules)
Some checks failed
CI / Lint and Format (pull_request) Failing after 2m56s
CI / Type Check (pull_request) Successful in 2m53s
CI / Security Check (pull_request) Failing after 3m45s
CI / Code Quality Checks (pull_request) Successful in 2m16s
CI / Unit Tests (pull_request) Failing after 3m11s
CI / Full Test Suite (pull_request) Has been skipped
CI / Integration Tests (pull_request) Successful in 2m50s
CI / Smoke Tests (pull_request) Failing after 2m45s
0b6dcf30e0
Centralize the attachment_threshold (4000) and 8MB cap (8*1024*1024) magic
numbers pulled from the Forgejo #273 allowlist rules, implemented as
DEFAULT_ATTACHMENT_THRESHOLD / DEFAULT_ATTACHMENT_SIZE_CAP in
runtime/discord_response.py. Add a comment linking back to #273 so a future
maintainer can audit the source.

Acceptance: from tests.unit._constants import ATTACHMENT_THRESHOLD_BYTES,
MAX_DISCORD_FILE_BYTES; ruff check tests/unit/ clean.
test(#280): add deterministic MeshIntentResult factory helpers for five shapes
Some checks are pending
CI / Lint and Format (pull_request) Waiting to run
CI / Type Check (pull_request) Waiting to run
CI / Security Check (pull_request) Waiting to run
CI / Code Quality Checks (pull_request) Waiting to run
CI / Unit Tests (pull_request) Waiting to run
CI / Integration Tests (pull_request) Waiting to run
CI / Full Test Suite (pull_request) Blocked by required conditions
CI / Smoke Tests (pull_request) Waiting to run
d4a9ad629a
Exposes short / long_prose / code_block / with_file / research factory
functions in tests/unit/factories.py, each returning a fully-formed
MeshIntentResult with a fixed epoch clock, hardcoded IDs/channel/message
bodies, and a real bytes attachment + filename for the with-file shape.
Rides the existing scaffolding PR #283 (issue #280); fixture-only, no
src/ changes. Smoke tests construct all five and assert pairwise
distinctness; ruff check clean.
test(#280): add reusable Discord HTTP boundary mock with outgoing-call recorder
Some checks are pending
CI / Lint and Format (pull_request) Waiting to run
CI / Type Check (pull_request) Waiting to run
CI / Security Check (pull_request) Waiting to run
CI / Code Quality Checks (pull_request) Waiting to run
CI / Unit Tests (pull_request) Waiting to run
CI / Integration Tests (pull_request) Waiting to run
CI / Full Test Suite (pull_request) Blocked by required conditions
CI / Smoke Tests (pull_request) Waiting to run
28c5660d5f
Provides tests/unit/discord_boundary.py: a FakeChannel plus FakeResponseTarget
and FakeGateway that mock Discord's HTTP boundary so DiscordBotService._run_intent
can be driven with zero network. Captures every outgoing call into a recorder:
("send", text), ("send_file", filename, bytes), ("send_embed", title, desc),
("typing",). Fake send returns a Message with deterministic id/channel_id and
never raises. boundary() assembles a fully-wired service; acceptance smoke
drives a factories.short() result through _run_intent and asserts the recorder
captured at least one entry.

Refs: #280
Kanban: t_c43efdf5
test(#280): back delivery-pipeline scaffolding to single smoke test (scenario tests stay on sibling cards)
Some checks failed
CI / Lint and Format (pull_request) Failing after 2m56s
CI / Type Check (pull_request) Successful in 2m52s
CI / Security Check (pull_request) Failing after 4m1s
CI / Code Quality Checks (pull_request) Successful in 2m16s
CI / Unit Tests (pull_request) Failing after 3m11s
CI / Full Test Suite (pull_request) Has been skipped
CI / Integration Tests (pull_request) Successful in 2m46s
CI / Smoke Tests (pull_request) Failing after 2m47s
c376b7d92e
test(#280): parametrized text-only scenarios for short, long-prose, code-block
Some checks failed
CI / Lint and Format (pull_request) Failing after 2m57s
CI / Type Check (pull_request) Successful in 2m56s
CI / Security Check (pull_request) Failing after 3m49s
CI / Code Quality Checks (pull_request) Successful in 2m16s
CI / Unit Tests (pull_request) Failing after 3m17s
CI / Full Test Suite (pull_request) Has been skipped
CI / Integration Tests (pull_request) Successful in 2m48s
CI / Smoke Tests (pull_request) Failing after 2m47s
d24492c0af
test(#280): parametrized with-file scenarios for oversized attachment path (#273)
Some checks are pending
CI / Lint and Format (pull_request) Waiting to run
CI / Type Check (pull_request) Waiting to run
CI / Security Check (pull_request) Waiting to run
CI / Code Quality Checks (pull_request) Waiting to run
CI / Unit Tests (pull_request) Waiting to run
CI / Integration Tests (pull_request) Waiting to run
CI / Full Test Suite (pull_request) Blocked by required conditions
CI / Smoke Tests (pull_request) Waiting to run
e7827cb867
test(#280): parametrized research-intent scenario for embed path (#271, #272)
Some checks failed
CI / Lint and Format (pull_request) Failing after 2m57s
CI / Type Check (pull_request) Successful in 2m52s
CI / Security Check (pull_request) Failing after 3m48s
CI / Code Quality Checks (pull_request) Successful in 2m16s
CI / Unit Tests (pull_request) Failing after 3m9s
CI / Full Test Suite (pull_request) Has been skipped
CI / Integration Tests (pull_request) Successful in 2m50s
CI / Smoke Tests (pull_request) Failing after 2m45s
39ad081175
Mark merged commit 350478c2cf into master 2026-08-20 10:14:20 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/mesh-seed!283
No description provided.