feat: public API, SEO and existing surfaces

This commit is contained in:
Florian Sylvain committed 2026-11-03 03:58:10 +01:00
1 parent 45fbbc33b1
commit c390fcfe8d
103 files changed
+4476 -231

No files matched your search

+11 -7
View File
@@ -29,11 +29,11 @@ Feature: SEO output backend, resolved SEO object, non-persisting check, list sta
Scenario: The object has the documented shape
When an anonymous caller sends GET /v1/article/12/seo
Then the status is 200
And the body has exactly the keys title, description, canonical_url, robots, og, twitter, image, authors, published_at, modified_at, fallbacks and json_ld
And og has exactly the keys type, title, description, image, image_alt, url, site_name and locale
And the body has exactly the keys title, description, canonical_url, robots, og, twitter, image, authors, published_at, modified_at, fallbacks, json_ld, lang and alternates
And og has exactly the keys type, title, description, image, image_alt, url, site_name, locale and locale_alternates
And twitter has exactly the keys card, title, description, image and image_alt
And image has exactly the keys url, alt and source
And fallbacks has exactly the keys title, description, image and canonical
And fallbacks has exactly the keys title, description, image, canonical and site_text_skipped
And the body has no body, no id and no seo_dismissed key
Scenario: A bare article resolves every output through the fallbacks
@@ -43,9 +43,10 @@ Feature: SEO output backend, resolved SEO object, non-persisting check, list sta
And canonical_url is "https://www.renew.example/how-we-price-a-bathroom-renovation"
And robots is "index, follow"
And image is {"url": "https://www.renew.example/static/uploadedImages/7.png", "alt": "", "source": "site"}
And og is {"type": "article", "title": "How we price a bathroom renovation | Renew", "description": "We price by the square metre.", "image": "https://www.renew.example/static/uploadedImages/7.png", "image_alt": "", "url": "https://www.renew.example/how-we-price-a-bathroom-renovation", "site_name": "Renew", "locale": "en"}
And og is {"type": "article", "title": "How we price a bathroom renovation | Renew", "description": "We price by the square metre.", "image": "https://www.renew.example/static/uploadedImages/7.png", "image_alt": "", "url": "https://www.renew.example/how-we-price-a-bathroom-renovation", "site_name": "Renew", "locale": "en", "locale_alternates": []}
And lang is "" and alternates is [] because this article is unassigned, so the legacy canonical and the raw Site.Locale apply
And twitter is {"card": "summary_large_image", "title": "How we price a bathroom renovation | Renew", "description": "We price by the square metre.", "image": "https://www.renew.example/static/uploadedImages/7.png", "image_alt": ""}
And fallbacks is {"title": "title", "description": "body", "image": "site", "canonical": "site"}
And fallbacks is {"title": "title", "description": "body", "image": "site", "canonical": "site", "site_text_skipped": false}
And published_at is "2026-09-01T08:00:00Z" and modified_at is "2026-09-10T09:30:00Z"
Scenario Outline: The title chain and the template
@@ -118,8 +119,10 @@ Feature: SEO output backend, resolved SEO object, non-persisting check, list sta
And fallbacks.canonical is "<source>"
And robots is "<result>"
And for an assigned article the canonical is built from the Public URL pattern with {lang} and {slug} and fallbacks.canonical is "pattern", while this table (unassigned article, or a site with no pattern) keeps the legacy base_url rule, and og:locale derivation follows features/localization_public_api_and_surfaces.feature
Examples:
| canonical | noindex | robots | resolved | source | result |
| canonical | noindex | robots | resolved | source | result |
| | false | index | https://www.renew.example/how-we-price-a-bathroom-renovation | site | index, follow |
| | false | noindex | https://www.renew.example/how-we-price-a-bathroom-renovation | site | noindex, nofollow |
| https://other.example/a | false | index | https://other.example/a | canonical_url | index, follow |
@@ -574,7 +577,8 @@ Feature: SEO output backend, resolved SEO object, non-persisting check, list sta
Then the status is 200
And the body is a JSON array of 2 items: {"url": "https://www.renew.example/how-we-price-a-bathroom-renovation", "modified_at": "2026-09-10T09:30:00Z", "noindex": false} and the item of the article 16
And the header X-Total-Count is "2"
And each item has exactly the keys url, modified_at and noindex
And each item has exactly the keys url, modified_at, noindex and lang
And only published versions in enabled languages are listed, each at its localized address when the site has a Public URL pattern
Scenario: Noindex articles are included with the flag
Given the online article 16 has noindex true