Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions openlibrary/plugins/openlibrary/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,11 @@ def POST(self, key):
if not user or user.key != key:
raise web.seeother(f'/account/login?redir_url={i.redir_url}')

# Validate that the publisher account exists
publisher_account = accounts.find(username=i.publisher)
if not publisher_account:
raise web.notfound("Publisher not found")

username = user.key.split('/')[2]
action = PubSub.subscribe if i.state == '0' else PubSub.unsubscribe
action(username, i.publisher)
Expand Down
41 changes: 41 additions & 0 deletions openlibrary/plugins/openlibrary/tests/test_followsapi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Tests for the /follows.json API endpoint."""
import pytest
import web

from openlibrary import accounts
from openlibrary.plugins.openlibrary.api import patrons_follows_json


class TestPatronFollowsAPI:
"""Test the /follows.json API endpoint for following/unfollowing patrons."""

def test_post_follows_nonexistent_publisher_returns_404(self, mock_site, monkeypatch):
"""Test that following a non-existent publisher returns 404.

This test validates that the fix prevents following non-existent publishers.
"""
# Setup mock user and input
mock_user = web.storage()
mock_user.key = '/people/test_user'

mock_input = web.storage(
publisher='nonexistent_user',
redir_url='/',
state='0' # subscribe
)

monkeypatch.setattr(web, 'input', lambda: mock_input)
monkeypatch.setattr(accounts, 'get_current_user', lambda: mock_user)

# Mock accounts.find to return None for nonexistent user
monkeypatch.setattr(accounts, 'find', lambda **kwargs: None)

# Create the API handler instance
handler = patrons_follows_json()

# This should now return a 404 after the fix
with pytest.raises(Exception) as exc_info:
handler.POST('/people/test_user')

# Check that it's a 404 error (web.notfound)
assert 'notfound' in str(exc_info.type).lower() or '404' in str(exc_info.value)