Skip to content

feat(ses): RFC 5322 / MIME builder for TestRenderEmailTemplate#760

Merged
vieiralucas merged 2 commits intomainfrom
worktree-batch4-ses-mime-builder
Apr 25, 2026
Merged

feat(ses): RFC 5322 / MIME builder for TestRenderEmailTemplate#760
vieiralucas merged 2 commits intomainfrom
worktree-batch4-ses-mime-builder

Conversation

@vieiralucas
Copy link
Copy Markdown
Member

@vieiralucas vieiralucas commented Apr 25, 2026

Summary

  • New fakecloud_ses::mime::build_message produces RFC-5322-compliant MIME from a templated subject + text + html
  • Adds Date, Message-ID, MIME-Version: 1.0, RFC 2047 encoded-word subject for non-ASCII, multipart/alternative + boundary when both bodies are present, quoted-printable transfer encoding for non-ASCII or HTML, 7bit for plain ASCII text
  • Wires it into TestRenderEmailTemplate (the only user-facing site that returned simplified MIME); previous output was missing Date / Message-ID / proper multipart

Test plan

  • Unit tests in mime.rs: 7bit ASCII text, single HTML part, multipart/alternative with both parts, RFC 2047 encoded-word subject, quoted-printable body for non-ASCII
  • E2E ses_mime.rs: render templated email via SDK, parse with mail-parser, assert multipart structure, headers, both bodies; second test exercises non-ASCII subject + body round-trip
  • All 190 fakecloud-ses unit tests still green
  • cargo clippy --workspace --all-targets -- -D warnings clean
  • cargo fmt --check clean

Summary by cubic

Return fully formed RFC 5322/MIME messages from SES TestRenderEmailTemplate, adding Date/Message-ID and fixing multipart and encoding rules with correct CRLF handling. Output now parses cleanly in standard libraries and matches real SES.

  • New Features

    • Build compliant messages: Date, Message-ID, MIME-Version, RFC 2047 subject.
    • Correct structure/encodings: multipart/alternative; 7bit for ASCII; quoted-printable for non-ASCII/HTML.
    • Integrated into TestRenderEmailTemplate; E2E verifies parsing and non-ASCII round-trip with mail-parser.
  • Bug Fixes

    • Normalize line endings to CRLF for 7bit and quoted-printable bodies; avoid doubling CRLF and stop emitting =0A/=0D.
    • Unit tests cover CRLF normalization and quoted-printable newlines.

Written for commit 5a848b9. Summary will update on new commits.

The previous TestRenderEmailTemplate output emitted only Subject +
MIME-Version + Content-Type + body. mail-parser, Python email, and Node
mailparser accept it loosely but it is missing Date, Message-ID, and a
proper multipart structure when both text and HTML parts are present.

The new fakecloud_ses::mime::build_message produces RFC-5322-compliant
messages with:
- Date (RFC 2822) and Message-ID (UUID@fakecloud.local)
- MIME-Version: 1.0
- Subject with RFC 2047 encoded-word when non-ASCII
- multipart/alternative + boundary when both text + html present;
  single-part otherwise
- Content-Transfer-Encoding: 7bit for plain ASCII bodies,
  quoted-printable for non-ASCII or HTML safety

E2E parses the rendered template with mail-parser and asserts the
multipart structure, headers, and a non-ASCII roundtrip survives both
the encoded-word subject and quoted-printable body decoding.

New deps: base64 in fakecloud-ses, mail-parser as a fakecloud-e2e
dev-dep for verification.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

2 issues found across 7 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/fakecloud-ses/src/mime.rs">

<violation number="1" location="crates/fakecloud-ses/src/mime.rs:81">
P2: Line-ending normalization for 7bit bodies corrupts existing CRLF into `\r\r\n`.</violation>

<violation number="2" location="crates/fakecloud-ses/src/mime.rs:91">
P2: Quoted-printable encoding converts newlines to `=0A` instead of emitting CRLF line breaks.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread crates/fakecloud-ses/src/mime.rs Outdated
Comment thread crates/fakecloud-ses/src/mime.rs Outdated
- quoted_printable_encode: emit literal CRLF for any \r, \n, or \r\n
  hard line break instead of =0A / =0D. RFC 2045 specifies CRLF for hard
  breaks; verifiers and parsers reject =0A in body content.
- normalize_crlf (replaces the prior naive `replace('\n', "\r\n")` for
  7bit bodies): walk bytes and collapse any mix of \r\n, \r, \n into
  canonical \r\n exactly once. Prior version would corrupt existing CRLF
  into \r\r\n because the \n inside \r\n got replaced.
- Unit tests cover: quoted-printable emits CRLF for newlines, mixed
  line-ending input collapses cleanly, normalize_crlf does not double
  existing CRLF.
@vieiralucas vieiralucas merged commit 5bd6816 into main Apr 25, 2026
22 checks passed
@vieiralucas vieiralucas deleted the worktree-batch4-ses-mime-builder branch April 25, 2026 20:20
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 25, 2026

Codecov Report

❌ Patch coverage is 98.33333% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/fakecloud-ses/src/mime.rs 98.28% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

vieiralucas added a commit that referenced this pull request Apr 25, 2026
Three pre-existing test bugs that the protocol-map fix surfaced because
this branch is the first to actually run the full conformance + e2e
suites against post-#761 main:

- crates/fakecloud-conformance/tests/logs.rs::logs_list_log_groups_for_query
- crates/fakecloud-e2e/tests/logs.rs::logs_misc_stubs

Both tests called `ListLogGroupsForQuery` with a synthetic queryId. PR
#761's Cubic round (commit ad110ec) tightened the impl to return
`ResourceNotFoundException` for unknown queryIds — matching real AWS —
but the test sites still expected the previous "silently empty" answer.
Fix: create a real query via `StartQuery` first, then look it up.

- crates/fakecloud-e2e/tests/stepfunctions.rs::wait_for_execution

50 polls * 50ms = 2.5s. The PR-#757 SNS RSA-SHA256 signing + post-#760
SES-MIME work can push first-touch latency past that budget on
GitHub-hosted runners under parallel load. Bump the budget to 10s.
Locally executions still complete in <2s.

The conformance probe-map change in this PR exposed these because
`paths-filter` only triggers conformance + e2e when the conformance
crate changes, so the failing tests rode in unnoticed.
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.

1 participant