Skip to content

M19.1: Pin MAIL_OUTBOUND_ENABLED=true in phpunit.xml#69

Merged
n8bar merged 2 commits into
mainfrom
claude/m19.1-notification-test-flake
May 10, 2026
Merged

M19.1: Pin MAIL_OUTBOUND_ENABLED=true in phpunit.xml#69
n8bar merged 2 commits into
mainfrom
claude/m19.1-notification-test-flake

Conversation

@n8bar
Copy link
Copy Markdown
Owner

@n8bar n8bar commented May 10, 2026

Summary

  • Adds MAIL_OUTBOUND_ENABLED=true to phpunit.xml's <php> block to give the test suite a deterministic mail-outbound posture independent of whatever .env exists at run time.
  • Updates the M19.1 strategy doc: carried-in finding gets a Resolution note pointing to M19.1: InvoiceNotificationTest + InvoiceDeliveryTest fail in CI #68; the Phase 1 exit criterion for the CI flakiness is checked off.

Fixes #68.

Root cause

PR Tests has been red on every recent run (10+ in a row). Failures concentrate in InvoiceNotificationTest and InvoiceDeliveryTest, with the same shape: assertions expecting status='queued' see status='skipped', and dispatch assertions see no job pushed.

The chain:

  1. .env.example ships MAIL_OUTBOUND_ENABLED=false (a sensible cautious default for fresh installs).
  2. The PR Tests workflow does cp .env.example .env before running tests. There is no .env.testing, and phpunit.xml doesn't pin the value, so false survives into the test environment.
  3. With mail.safety.outbound_enabled === false, InvoiceDeliveryService::skipReason() returns "Outbound mail is temporarily disabled." for every queue() call.
  4. Rows get written with status='skipped' instead of 'queued', and DeliverInvoiceMail::dispatch() is never called.
  5. Tests that explicitly assert status='queued' or "this job was pushed" fail. Tests that don't check status pass — which is why this drifted past prior reviews until the failure pattern was wide enough to notice.

Locally we don't see it because dev .env files have MAIL_OUTBOUND_ENABLED=true.

What changed

phpunit.xml:

<env name="MAIL_OUTBOUND_ENABLED" value="true"/>

Same shape as the existing MAIL_MAILER=array and QUEUE_CONNECTION=sync overrides — test-deterministic config that doesn't depend on whatever .env is on disk. .env.example stays cautious for fresh installs.

docs/strategies/19.1_NOTIFICATION_COVERAGE_AUDIT.md:

Verification

  • ./vendor/bin/sail artisan test → 334/334 passing locally with .env intentionally set to MAIL_OUTBOUND_ENABLED=false to mirror CI conditions. Override wins.
  • InvoiceDeliveryTest::test_manual_send_is_skipped_when_outbound_mail_is_disabled already sets config(['mail.safety.outbound_enabled' => false]) inline, so it's insulated from the env-level flip.
  • InvoiceNotificationTest (17/17) and InvoiceDeliveryTest (26/26) both green under the same CI-mirror conditions.

Test plan

Process notes

This is the first GitHub Issue / PR pair under the M19 Issues trial documented in docs/DOC_ROLES.md and the M19 milestone doc. The split-of-concerns followed: issue body holds the bug report, this PR description holds the fix writeup. M20 kickoff revisits whether the trial sticks.

n8bar added 2 commits May 9, 2026 20:19
…in finding

InvoiceNotificationTest and InvoiceDeliveryTest have been failing across
recent CI runs because `.env.example` ships `MAIL_OUTBOUND_ENABLED=false`
and the PR Tests workflow copies it verbatim into `.env`. With outbound
disabled, `InvoiceDeliveryService::skipReason()` returns
"Outbound mail is temporarily disabled." for every queue() call, so
delivery rows land with `status='skipped'` and `DeliverInvoiceMail`
never dispatches. Tests that don't check status slipped through, masking
the breakage.

Adding `MAIL_OUTBOUND_ENABLED=true` to phpunit.xml's `<php>` block
forces a deterministic mail-outbound posture for tests, independent of
whatever `.env` happens to be lying around. Same shape as the existing
`MAIL_MAILER=array`, `QUEUE_CONNECTION=sync` overrides.

Verified locally: 334/334 tests pass with the override in place and
`.env` set to `MAIL_OUTBOUND_ENABLED=false` (CI-mirror conditions). The
one test that intentionally exercises the disabled path
(`InvoiceDeliveryTest::test_manual_send_is_skipped_when_outbound_mail_is_disabled`)
sets the config to false inline via `config([...])` and is unaffected.

Strategy doc 19.1 updates: carried-in finding section gets a Resolution
note pointing to the tracking issue; the Phase 1 exit criterion for the
flakiness is checked off.

Fixes #68
M18.2 (Content Audit and Production) and M18.3 (Site Architecture and
Publishing) are complete; applying the project's `x` prefix convention
for completed strategy docs.

Bundled with the M19.1 test fix PR (#69) for merge-time efficiency.
@n8bar n8bar merged commit 1d58443 into main May 10, 2026
1 check passed
@n8bar n8bar deleted the claude/m19.1-notification-test-flake branch May 10, 2026 02:38
n8bar added a commit that referenced this pull request May 10, 2026
The InvoiceNotificationTest CI flakiness has been resolved (#68 / #69).
Rewriting the carried-in finding section in past tense so it reads as
historical context, with a one-line summary of the root cause and
pointers to the issue/PR for the full story.

Section heading carries `(resolved)` to make the status visible at a
glance. Phase 1 actionable todo list (§1–§4) is unchanged.
@n8bar n8bar mentioned this pull request May 10, 2026
3 tasks
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.

M19.1: InvoiceNotificationTest + InvoiceDeliveryTest fail in CI

1 participant