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
2 changes: 1 addition & 1 deletion backend/api/cms/news/queries/news_article.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def news_article(hostname: str, slug: str, language: str) -> NewsArticle | None:
if not site:
raise ValueError(f"Site {hostname} not found")

article = NewsArticleModel.objects.in_site(site).filter(slug=slug).first()
article = NewsArticleModel.objects.in_site(site).filter(slug=slug, live=True).first()

if not article:
return None
Expand Down
2 changes: 1 addition & 1 deletion backend/api/cms/page/queries/cms_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def cms_page(
if not site:
return SiteNotFoundError(message=f"Site `{hostname}` not found")

page = GenericPageModel.objects.in_site(site).filter(slug=slug).first()
page = GenericPageModel.objects.in_site(site).filter(slug=slug, live=True).first()

if not page:
return None
Expand Down
47 changes: 47 additions & 0 deletions backend/api/cms/tests/news/test_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,53 @@ def test_cannot_get_draft_news_article(
assert response["data"]["newsArticle"] is None


def test_cannot_get_draft_base_article_even_if_translation_is_live(
graphql_client,
locale,
):
"""
Test that a draft base article cannot be fetched even if a translation exists that is live.
This ensures the live=True filter is applied to the initial queryset.
"""
user = UserFactory(full_name="marco world")
parent = GenericPageFactory()
# Create a draft base article (live=False)
article = NewsArticleFactory(
title="Article 1",
parent=parent,
owner=user,
slug="slug",
first_published_at=None,
live=False,
)
SiteFactory(hostname="pycon", port=80, root_page=parent)

# Create a live Italian translation
it_article = article.copy_for_translation(locale=locale("it"))
it_article.title = "Article Italian"
it_article.save_revision().publish()

query = """query NewsArticle(
$hostname: String!,
$slug: String!,
$language: String!
) {
newsArticle(hostname: $hostname, slug: $slug, language: $language) {
id
title
authorFullname
}
}"""

# Even though the Italian translation is live, the base article is draft
# so it should not be fetchable
response = graphql_client.query(
query, variables={"hostname": "pycon", "slug": article.slug, "language": "it"}
)

assert response["data"]["newsArticle"] is None


def test_get_news_article_another_locale(
graphql_client,
locale,
Expand Down
44 changes: 44 additions & 0 deletions backend/api/cms/tests/page/queries/test_cms_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,50 @@ def test_cannot_fetch_draft_pages(graphql_client, locale):
assert response["data"]["cmsPage"] is None


def test_cannot_fetch_draft_base_page_even_if_translation_is_live(graphql_client, locale):
"""
Test that a draft base page cannot be fetched even if a translation exists that is live.
This ensures the live=True filter is applied to the initial queryset.
"""
parent = GenericPageFactory()
# Create a draft base page (live=False)
page = GenericPageFactory(
slug="bubble-tea",
locale=locale("en"),
parent=parent,
title="Bubble",
body__0__text_section__title__value="I've Got a Lovely Bunch of Coconuts",
live=False,
)

SiteFactory(hostname="pycon", port=80, root_page=parent)

# Create a live Italian translation
it_page = page.copy_for_translation(locale=locale("it"))
it_page.title = "Bubble Italian"
it_page.save_revision().publish()

query = """
query Page ($hostname: String!, $language: String!, $slug: String!) {
cmsPage(hostname: $hostname, language: $language, slug: $slug){
...on GenericPage {
title
slug
}
}
}
"""

# Even though the Italian translation is live, the base page is draft
# so it should not be fetchable
response = graphql_client.query(
query, variables={"hostname": "pycon", "slug": "bubble-tea", "language": "it"}
)

assert not response.get("errors")
assert response["data"]["cmsPage"] is None


def test_page_for_unknown_locale(graphql_client, locale):
parent = GenericPageFactory()
page = GenericPageFactory(
Expand Down
Loading