Skip to content

Tests for attachments, clean-up actions, rules and middleware - #3

Open
ravimehra9911 wants to merge 1 commit into
mainfrom
claude/vigorous-williams-a16e06
Open

ravimehra9911 wants to merge 1 commit into
mainfrom
claude/vigorous-williams-a16e06

Conversation

@ravimehra9911

Copy link
Copy Markdown
Owner

Adds 63 Vitest tests (100 in total) for MailClean's highest-risk code, which had none: deleting and archiving mail, unsubscribing, rules, attachment downloads and the request middleware. No app code changed.

No real mailbox or Downloads folder is touched. The IMAP functions and moveMessages are mocked, each test file uses its own temp DATA_DIR, and the attachment tests point os.homedir() at a temp folder.

Covered

  • attachments – format grouping; skipping attachments already saved and downloading again when the file changed or was removed; adopting a v1.8.0 file only when no other attachment claims it; name (2).pdf; .part removed when the stream fails; cancel finishing the current file, then status cancelled; status leaving running when getAccount throws; openFolder rejecting files, outside paths, MailCleanEvil and ...
  • actions – keep starred/important; keep newest N, counted within the current view; archive touching only inbox mail; the right ids per account; a provider error leaving local copies; one-click unsubscribe never posting to private addresses or plain http; the bulk unsubscribe plan.
  • rules – matching by sender, Gmail tab and older-than; starred and important always kept; disabled rules skipped; one account at a time.
  • stats – scopeSql; the "Mostly unread" and newsletter filters, which agree with the Overview count.
  • middleware – token required when MAILCLEAN_TOKEN is set; DNS-rebinding host check; 423 while locked except /api/lock; old Vercel address redirected.

Checks

  • npm run typecheck, npm run lint and npm test pass locally.
  • I broke the guarded behaviour 22 times, one change at a time, and every break made a test fail. Examples: removing + path.sep from the openFolder check, the old "Mostly unread" HAVING clause, dropping the .part cleanup, and always setting status to done.

Adds 63 Vitest tests for the code that moves mail, unsubscribes, runs rules
and saves attachments. No mailbox is contacted: the IMAP functions and
moveMessages are mocked, each file uses a temp DATA_DIR, and the attachment
tests point os.homedir() at a temp folder so Downloads/MailClean is never real.

- attachments: format grouping, skipping saved parts, adopting a legacy file
  only when unclaimed, "name (2).pdf", .part cleanup on stream errors, cancel
  finishing the current file, status leaving "running" when getAccount throws,
  openFolder rejecting files, outside paths, MailCleanEvil and "..".
- actions: keep starred/important, keep newest N (within the scope), archive
  only inbox mail, ids passed per account, one-click SSRF guard, bulk plan.
- rules: sender / Gmail tab / older-than matching, flagged mail always kept.
- stats: scopeSql, "Mostly unread" and newsletter filters.
- middleware: token, DNS-rebinding host check, 423 lock except /api/lock,
  old Vercel host redirect.

No app code changed.
@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
mailclean Ready Ready Preview Oct 25, 2026 5:30am UTC

This branch was successfully deployed

1 active deployment
Preview — 1d99bd8c Deployed Oct 25, 2026 by vercel[bot]
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