From 39924e69aba4a1c3342ccef319eddffe5fb93dd9 Mon Sep 17 00:00:00 2001 From: Leon Date: Wed, 16 Jul 2025 09:52:04 +0200 Subject: [PATCH] test: newsletter update, delete, feed --- backend/app/routers/newsletters.py | 15 ++++++++++++ backend/app/tests/test_crud.py | 39 ++++++++++++++++++++++++++++++ backend/app/tests/test_routers.py | 33 +++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/backend/app/routers/newsletters.py b/backend/app/routers/newsletters.py index ab992b5..83f0d1b 100644 --- a/backend/app/routers/newsletters.py +++ b/backend/app/routers/newsletters.py @@ -13,6 +13,8 @@ from app.crud.newsletters import ( update_newsletter, ) from app.schemas.newsletters import Newsletter, NewsletterCreate, NewsletterUpdate +from app.schemas.entries import Entry, EntryCreate +from app.crud.entries import create_entry logger = get_logger(__name__) router = APIRouter() @@ -70,3 +72,16 @@ def delete_existing_newsletter(newsletter_id: int, db: Session = Depends(get_db) logger.warning(f"Newsletter with id={newsletter_id} not found, cannot delete") raise HTTPException(status_code=404, detail="Newsletter not found") return db_newsletter + + +@router.post("/newsletters/{newsletter_id}/entries", response_model=Entry) +def create_newsletter_entry( + newsletter_id: int, entry: EntryCreate, db: Session = Depends(get_db) +): + """Create a new entry for a specific newsletter.""" + logger.info(f"Request to create entry for newsletter_id={newsletter_id}") + db_newsletter = get_newsletter(db, newsletter_id=newsletter_id) + if db_newsletter is None: + logger.warning(f"Newsletter with id={newsletter_id} not found, cannot create entry") + raise HTTPException(status_code=404, detail="Newsletter not found") + return create_entry(db=db, entry=entry, newsletter_id=newsletter_id) diff --git a/backend/app/tests/test_crud.py b/backend/app/tests/test_crud.py index 8afe8ce..145bdde 100644 --- a/backend/app/tests/test_crud.py +++ b/backend/app/tests/test_crud.py @@ -170,3 +170,42 @@ def test_get_entries_by_newsletter(db_session: Session): entries = get_entries_by_newsletter(db_session, newsletter.id) assert len(entries) == 2 assert entries[0].subject == "Entry 1" + + +def test_update_newsletter(db_session: Session): + """Test updating a newsletter.""" + unique_email = f"sender_{uuid.uuid4()}@test.com" + newsletter_data = NewsletterCreate( + name="Newsletter to Update", sender_emails=[unique_email] + ) + newsletter = create_newsletter(db_session, newsletter_data) + + from app.schemas.newsletters import NewsletterUpdate + + updated_email = f"updated_sender_{uuid.uuid4()}@test.com" + updated_newsletter_data = NewsletterUpdate(name="Updated Newsletter", sender_emails=[updated_email]) + from app.crud.newsletters import update_newsletter + updated_newsletter = update_newsletter(db_session, newsletter.id, updated_newsletter_data) + + assert updated_newsletter.name == "Updated Newsletter" + assert len(updated_newsletter.senders) == 1 + assert updated_newsletter.senders[0].email == updated_email + + +def test_delete_newsletter(db_session: Session): + """Test deleting a newsletter.""" + unique_email = f"sender_{uuid.uuid4()}@test.com" + newsletter_data = NewsletterCreate( + name="Newsletter to Delete", sender_emails=[unique_email] + ) + newsletter = create_newsletter(db_session, newsletter_data) + + from app.crud.newsletters import delete_newsletter + deleted_newsletter = delete_newsletter(db_session, newsletter.id) + + assert deleted_newsletter.id == newsletter.id + assert deleted_newsletter.name == "Newsletter to Delete" + + # Verify it's actually deleted + from app.crud.newsletters import get_newsletter + assert get_newsletter(db_session, newsletter.id) is None diff --git a/backend/app/tests/test_routers.py b/backend/app/tests/test_routers.py index 01bf0d4..c12563b 100644 --- a/backend/app/tests/test_routers.py +++ b/backend/app/tests/test_routers.py @@ -145,3 +145,36 @@ def test_get_nonexistent_newsletter(client: TestClient): response = client.get("/newsletters/999") assert response.status_code == 404 assert response.json() == {"detail": "Newsletter not found"} + + +def test_get_newsletter_feed(client: TestClient): + """Test generating a newsletter feed.""" + unique_email = f"feed_test_{uuid.uuid4()}@example.com" + newsletter_data = {"name": "Feed Test Newsletter", "sender_emails": [unique_email]} + create_response = client.post("/newsletters/", json=newsletter_data) + newsletter_id = create_response.json()["id"] + + # Add some entries to the newsletter + entry_data_1 = {"subject": "Test Entry 1", "body": "

Content 1

"} + client.post(f"/newsletters/{newsletter_id}/entries", json=entry_data_1) + entry_data_2 = {"subject": "Test Entry 2", "body": "

Content 2

"} + client.post(f"/newsletters/{newsletter_id}/entries", json=entry_data_2) + + response = client.get(f"/feeds/{newsletter_id}") + assert response.status_code == 200 + assert "application/atom+xml" in response.headers["content-type"] + assert f"Feed Test Newsletter" in response.text + import xml.etree.ElementTree as ET + root = ET.fromstring(response.text) + # Atom feed uses a namespace, so we need to include it in our tag searches + ns = {'atom': 'http://www.w3.org/2005/Atom'} + entry_titles = [entry.find('atom:title', ns).text for entry in root.findall('atom:entry', ns)] + assert "Test Entry 1" in entry_titles + assert "Test Entry 2" in entry_titles + + +def test_get_newsletter_feed_nonexistent_newsletter(client: TestClient): + """Test generating a feed for a nonexistent newsletter.""" + response = client.get("/feeds/999") + assert response.status_code == 404 + assert response.json() == {"detail": "Newsletter not found"}