bambuddy/backend/tests/integration/test_user_notifications_api.py
maziggy a6d307d739 Post work PR #693
Add tests, docs, and ruff fixes for per-user email notifications

  - Fix missing timezone import in email_service.py (F821)
  - Fix unused lambda arg in main.py asyncio done_callback (ARG005)
  - Fix E302 blank line spacing for mark_printer_stopped_by_user
  - Fix F821/UP037 forward reference in user_email_pref model
  - Fix SettingsPage test for duplicate "Notifications" text
  - Add backend unit tests for permissions, schemas, and templates
  - Add backend integration tests for user-notifications API
  - Add frontend tests for NotificationsPage
  - Add user_email_pref model import to test conftest
  - Update CHANGELOG and README
2026-03-17 12:24:36 +01:00

80 lines
3.1 KiB
Python

"""Integration tests for User Notifications API endpoints.
Tests the full request/response cycle for /api/v1/user-notifications/ endpoints.
"""
import pytest
from httpx import AsyncClient
class TestUserNotificationsAPI:
"""Integration tests for /api/v1/user-notifications/ endpoints."""
# ========================================================================
# GET /preferences — no auth
# ========================================================================
@pytest.mark.asyncio
@pytest.mark.integration
async def test_get_preferences_returns_defaults_when_no_auth(self, async_client: AsyncClient):
"""Without auth, GET should return all-enabled defaults."""
response = await async_client.get("/api/v1/user-notifications/preferences")
assert response.status_code == 200
data = response.json()
assert data["notify_print_start"] is True
assert data["notify_print_complete"] is True
assert data["notify_print_failed"] is True
assert data["notify_print_stopped"] is True
# ========================================================================
# PUT /preferences — no auth
# ========================================================================
@pytest.mark.asyncio
@pytest.mark.integration
async def test_update_preferences_fails_without_auth(self, async_client: AsyncClient):
"""Without auth enabled, PUT should return 400 (no user context)."""
data = {
"notify_print_start": False,
"notify_print_complete": True,
"notify_print_failed": True,
"notify_print_stopped": False,
}
response = await async_client.put("/api/v1/user-notifications/preferences", json=data)
assert response.status_code == 400
assert "Authentication must be enabled" in response.json()["detail"]
# ========================================================================
# Schema validation
# ========================================================================
@pytest.mark.asyncio
@pytest.mark.integration
async def test_update_preferences_rejects_missing_fields(self, async_client: AsyncClient):
"""PUT should reject requests missing required boolean fields."""
data = {
"notify_print_start": True,
# missing other fields
}
response = await async_client.put("/api/v1/user-notifications/preferences", json=data)
assert response.status_code == 422 # Pydantic validation error
@pytest.mark.asyncio
@pytest.mark.integration
async def test_update_preferences_rejects_invalid_type(self, async_client: AsyncClient):
"""PUT should reject values that cannot be coerced to boolean."""
data = {
"notify_print_start": [1, 2, 3],
"notify_print_complete": True,
"notify_print_failed": True,
"notify_print_stopped": True,
}
response = await async_client.put("/api/v1/user-notifications/preferences", json=data)
assert response.status_code == 422