Skip to content
Merged
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
12 changes: 8 additions & 4 deletions backend/routers/discovery_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

from backend.config import get_settings
from backend.database.connection import get_database_session
from backend.services.author_service import organization_slug_for_author
from backend.services.author_service import (
merged_author_id,
organization_slug_for_author,
)
from backend.services.content_negotiation_service import (
prefers_markdown,
public_page_headers,
Expand Down Expand Up @@ -222,9 +225,10 @@ def conference_task_page(
def author_page(
author_id: int, request: Request, db: Session = Depends(get_database_session)
) -> Response:
org_slug = organization_slug_for_author(db, author_id)
if org_slug:
target = f"/orgs/{org_slug}"
merged_into = merged_author_id(db, author_id)
org_slug = None if merged_into else organization_slug_for_author(db, author_id)
if merged_into or org_slug:
target = f"/authors/{merged_into}" if merged_into else f"/orgs/{org_slug}"
if request.url.query:
target = f"{target}?{request.url.query}"
return RedirectResponse(target, status_code=301)
Expand Down
16 changes: 10 additions & 6 deletions backend/services/author_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ def get_or_create_author_by_name(db: Session, name: str) -> DBAuthor:
return author


def merged_author_id(db: Session, author_id: int) -> Optional[int]:
"""Return the author an ID was merged into, or None if it was not merged."""
return (
db.query(AuthorAlias.author_id)
.filter(AuthorAlias.alias_id == author_id)
.scalar()
)


class AuthorService:
"""Service class for author-related operations."""

Expand All @@ -106,12 +115,7 @@ def __init__(self, db: Session):
def _resolve_author_id(self, author_id: str) -> int:
"""Map an author ID merged into another author to the surviving ID."""
requested_id = int(author_id)
merged_into = (
self.db.query(AuthorAlias.author_id)
.filter(AuthorAlias.alias_id == requested_id)
.scalar()
)
return merged_into or requested_id
return merged_author_id(self.db, requested_id) or requested_id

def get_authors(
self,
Expand Down
13 changes: 13 additions & 0 deletions backend/tests/test_search_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,19 @@ def test_merged_organization_slug_redirects_to_canonical_page(client):
assert response.headers["location"] == "/orgs/google?q=vision"


def test_merged_author_redirects_to_the_author_it_was_merged_into(client, monkeypatch):
monkeypatch.setattr(
discovery_pages,
"merged_author_id",
lambda db, author_id: 181986 if author_id == 251936 else None,
)
response = client.get("/authors/251936?has_code=true", follow_redirects=False)
assert response.status_code == 301
assert response.headers["location"] == "/authors/181986?has_code=true"


def test_author_naming_an_organization_redirects_to_its_page(client, monkeypatch):
monkeypatch.setattr(discovery_pages, "merged_author_id", lambda db, author_id: None)
monkeypatch.setattr(
discovery_pages,
"organization_slug_for_author",
Expand Down Expand Up @@ -556,6 +568,7 @@ def test_discovery_page_classes_support_head(client, monkeypatch, path, method_n
monkeypatch.setattr(
DiscoveryPageService, method_name, lambda self, *args, **kwargs: _page()
)
monkeypatch.setattr(discovery_pages, "merged_author_id", lambda db, author_id: None)
monkeypatch.setattr(
discovery_pages, "organization_slug_for_author", lambda db, author_id: None
)
Expand Down
Loading