Skip to content

🧪 test(api): email send_email, _get_smtp_config, test-email route#37

Merged
LinMoQC merged 2 commits intomainfrom
fix/smtp-from-fallback-prod-tweaks
Mar 27, 2026
Merged

🧪 test(api): email send_email, _get_smtp_config, test-email route#37
LinMoQC merged 2 commits intomainfrom
fix/smtp-from-fallback-prod-tweaks

Conversation

@LinMoQC
Copy link
Copy Markdown
Owner

@LinMoQC LinMoQC commented Mar 27, 2026

Mock aiosmtplib and fake DB session; cover smtp_from fallback and router branches.

Made-with: Cursor

Summary

Type of change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactor / code cleanup
  • CI / tooling

Related issue

Closes #

Changes

How to test

Screenshots (if applicable)

Checklist

  • My code follows the project's coding conventions
  • I have run ./lyra lint and there are no type errors
  • I have added/updated tests for the changed functionality
  • I have updated the documentation if behavior changed
  • The PR title follows Conventional Commits format (feat:, fix:, etc.)
  • I have read the CONTRIBUTING.md

Summary by CodeRabbit

  • Tests
    • Expanded async test coverage for email functionality and the email test endpoint, covering SMTP config validation, send outcomes, and handler responses.
  • Chores
    • Added project tooling configuration to improve automated review and repo path filtering.

Mock aiosmtplib and fake DB session; cover smtp_from fallback and router branches.

Made-with: Cursor
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 27, 2026

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

Project Deployment Actions Updated (UTC)
lyra-note-web Ready Ready Preview, Comment Mar 27, 2026 2:27am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

Caution

Review failed

Pull request was closed or merged during review

Warning

Ignoring CodeRabbit configuration file changes. For security, only the configuration from the base branch is applied for open source repositories.

📝 Walkthrough

Walkthrough

Adds unit tests for email functionality and a CodeRabbit configuration file. Tests exercise app.providers.email.send_email and _get_smtp_config across SMTP edge cases and the POST /config/test-email handler using async pytest and mocks; .coderabbit.yaml configures review settings and path-specific guidance.

Changes

Cohort / File(s) Summary
Email provider unit tests
apps/api/tests/unit/test_email_provider.py
New async pytest module covering send_email and _get_smtp_config: validates missing/whitespace fields, From-header fallback, TLS/port behavior, SMTP client setup, login failure path, and uses mocked aiosmtplib.SMTP.
Config test-email handler tests
apps/api/tests/unit/test_config_test_email.py
New tests for POST /config/test-email handler: sets env, fakes DB session, patches send_email with AsyncMock, and asserts expected responses for complete/incomplete configs and send failures.
CodeRabbit config
.coderabbit.yaml
Adds repository review configuration, language/path-specific instructions for web and api apps, auto-review settings, and path filters for noisy/generated files.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 I sniff the SMTP breeze tonight,

I hop through tests that catch the light,
Mocks in paw and assertions tight,
No stray mails take off in flight,
Hooray — the email path is right! ✉️

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly references the main changes: adding tests for email functions (send_email, _get_smtp_config) and the test-email route. It accurately summarizes the changeset's primary focus on test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/smtp-from-fallback-prod-tweaks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/api/tests/unit/test_email_provider.py (1)

13-20: Avoid process-wide env mutation at import time in this test module.

Setting defaults at module import can leak state across tests and makes outcomes depend on pre-existing CI/local env. Prefer an autouse fixture with monkeypatch so values are scoped and restored per test run.

Suggested refactor
-os.environ.setdefault("DATABASE_URL", "sqlite+aiosqlite:///:memory:")
-os.environ.setdefault("REDIS_URL", "redis://localhost:6379/0")
-os.environ.setdefault("JWT_SECRET", "test-secret-key-for-pytest")
-os.environ.setdefault("STORAGE_BACKEND", "local")
-os.environ.setdefault("STORAGE_LOCAL_PATH", "/tmp/lyranote-test-storage")
-os.environ.setdefault("OPENAI_API_KEY", "sk-test")
-os.environ.setdefault("DEBUG", "false")
+@pytest.fixture(autouse=True)
+def _env(monkeypatch: pytest.MonkeyPatch):
+    monkeypatch.setenv("DATABASE_URL", "sqlite+aiosqlite:///:memory:")
+    monkeypatch.setenv("REDIS_URL", "redis://localhost:6379/0")
+    monkeypatch.setenv("JWT_SECRET", "test-secret-key-for-pytest")
+    monkeypatch.setenv("STORAGE_BACKEND", "local")
+    monkeypatch.setenv("STORAGE_LOCAL_PATH", "/tmp/lyranote-test-storage")
+    monkeypatch.setenv("OPENAI_API_KEY", "sk-test")
+    monkeypatch.setenv("DEBUG", "false")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/tests/unit/test_email_provider.py` around lines 13 - 20,
Module-level os.environ.setdefault calls cause process-wide env mutation at
import; remove those top-level setdefault lines and instead add a pytest autouse
fixture (e.g., env_autouse) that uses pytest's monkeypatch to set the same keys
(DATABASE_URL, REDIS_URL, JWT_SECRET, STORAGE_BACKEND, STORAGE_LOCAL_PATH,
OPENAI_API_KEY, DEBUG) for each test and automatically restores them after each
run; update apps/api/tests/unit/test_email_provider.py (or a shared conftest.py)
to define this fixture so state is scoped per test and no longer mutated at
import time.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/tests/unit/test_email_provider.py`:
- Around line 245-310: Move the tests that exercise
app.domains.config.router.test_email out of the provider-focused test file and
into the config-domain test module: create or update the config-domain unit test
file to contain the TestConfigTestEmailRoute class and its test_* methods (which
reference test_email, _ConfigFakeSession, and _CfgRow), update the import paths
inside those tests to import test_email from app.domains.config.router, and
remove these tests from apps/api/tests/unit/test_email_provider.py so
provider-focused tests only cover app.providers.email.send_email; ensure any
fixtures or helper classes (_CfgRow, _ConfigFakeSession) are available or moved
along with the tests.
- Around line 64-77: Modify the test_returns_false_when_from_and_username_empty
test so it triggers the from_addr-empty branch in send_email: supply
smtp_config["smtp_username"] as a whitespace string (e.g., " ") so .strip()
yields an empty username check to pass but set the from_addr argument to a
string that becomes empty after .strip() (e.g., " ") as well; this ensures
send_email's logic in the send_email function exercises the if not from_addr
branch and returns False while SMTP is not called (verify
smtp_cls.assert_not_called()).

---

Nitpick comments:
In `@apps/api/tests/unit/test_email_provider.py`:
- Around line 13-20: Module-level os.environ.setdefault calls cause process-wide
env mutation at import; remove those top-level setdefault lines and instead add
a pytest autouse fixture (e.g., env_autouse) that uses pytest's monkeypatch to
set the same keys (DATABASE_URL, REDIS_URL, JWT_SECRET, STORAGE_BACKEND,
STORAGE_LOCAL_PATH, OPENAI_API_KEY, DEBUG) for each test and automatically
restores them after each run; update apps/api/tests/unit/test_email_provider.py
(or a shared conftest.py) to define this fixture so state is scoped per test and
no longer mutated at import time.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d1e87ff6-54c9-469a-a4e3-580cc992a909

📥 Commits

Reviewing files that changed from the base of the PR and between ca9485a and f55bff2.

📒 Files selected for processing (1)
  • apps/api/tests/unit/test_email_provider.py

Add .coderabbit.yaml (zh-CN, summary, path filters). Split config test-email handler tests into test_config_test_email.py; cover empty from_addr after strip.

Made-with: Cursor
@LinMoQC LinMoQC merged commit 4ea3a23 into main Mar 27, 2026
4 of 5 checks passed
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