readme, claude mds update info
This commit is contained in:
@@ -89,11 +89,17 @@ workers. Python >=3.13,<4.0, Poetry for dependency management.
|
||||
`src/service/email/templates/`), inline CSS (email clients don't support
|
||||
`<style>` reliably), `EmailMessage` with `set_content()` (plain-text
|
||||
fallback) + `add_alternative(html, subtype="html")`.
|
||||
- **Known gap**: the reset-password flow is a stub. `ResetEmailConsumer.process_message`
|
||||
only prints and acks — it never calls a sender — and
|
||||
`src/service/email/email_reset.py` is empty. `templates/reset.html` still
|
||||
has a hardcoded placeholder password. Don't assume reset emails actually
|
||||
send until this is wired up like `WelcomeEmailConsumer`/`DaemonEmailSender`.
|
||||
- Reset-password flow mirrors welcome: `ResetEmailSender`
|
||||
(`src/service/email/email_reset.py`) renders `templates/reset.html`
|
||||
(`{{ temp_password }}`, no longer hardcoded) the same way
|
||||
`DaemonEmailSender` does `welcome.html`. `ResetEmailConsumer.process_message`
|
||||
reads both `email` and `temp_password` from the message body and uses the
|
||||
same transient/permanent classification as `WelcomeEmailConsumer`.
|
||||
`EmailProducer.send_reset_email(email, temp_password)` takes the password
|
||||
as a second argument now. **Still missing**: nothing in the app actually
|
||||
calls `send_reset_email` yet — there's no password-reset route that
|
||||
generates a `temp_password` and publishes it. Don't assume the
|
||||
reset-password feature is reachable end-to-end until that route exists.
|
||||
|
||||
## Logging (`src/logging/`)
|
||||
|
||||
@@ -204,3 +210,18 @@ workers. Python >=3.13,<4.0, Poetry for dependency management.
|
||||
which broke refresh-token-cookie-dependent tests like logout).
|
||||
- `test_user_fixture` is `indirect=True` parametrized with
|
||||
`(direct_permissions, group)` tuples.
|
||||
- `tests/unit/test_consumers.py` covers `RabbitMQClient`/`WelcomeEmailConsumer`/
|
||||
`ResetEmailConsumer` entirely with mocks — no real broker involved.
|
||||
Pattern: `monkeypatch.setattr(rabbitmq_client_module.aio_pika, "connect_robust", ...)`
|
||||
patches the module attribute that `connect()` looks up at call time (not
|
||||
the `rabbitmq_client` singleton's method — that's a bound method, it has
|
||||
no attribute of its own to patch). `aio_pika.connect_robust`/`asyncio.sleep`
|
||||
must both be mocked when testing the retry loop, or the test really
|
||||
sleeps `2**attempt` seconds between attempts. `message.process(...)` is an
|
||||
async context manager, not a plain awaitable — mocking it needs a
|
||||
`MagicMock` with `__aenter__`/`__aexit__` set to `AsyncMock`s (see
|
||||
`make_fake_message()` in that file), not just `AsyncMock()`. When
|
||||
asserting on what a mocked async method returned, compare against
|
||||
`mock.return_value` (or a variable captured before assigning it), never
|
||||
against the mock itself — `some_mock is some_mock.return_value` is never
|
||||
true, they're two different objects.
|
||||
|
||||
Reference in New Issue
Block a user