170 lines
14 KiB
Gherkin
170 lines
14 KiB
Gherkin
Feature: Integration page documents every route an API key can call
|
|
|
|
As a developer building on RenewCMS
|
|
I want the API reference to cover content types, entries, built-in types, sites, authors and media purge
|
|
So that I can use every route my API key can call without reading the source
|
|
|
|
Background:
|
|
Given the SPA route /integration of the verified back-office (static page, no /v1 call, web/ only)
|
|
And the page follows docs/design/screens/integration.md, sections "Custom content types round" and "Final round"
|
|
And the boards are IntegrationPage.dc.html, IntegrationSearch.dc.html and states 8c, 8d, 8f and 9a to 9j of "RenewCMS Screens Back-office.dc.html"
|
|
And endpoint rows, groups, index and session-only sub-groups come from the catalogue the board builds with A(...), G, IDX and sessGroups
|
|
And every sample and count follows the real API, not the board's illustrative values
|
|
And the components are Nuxt UI v4 with design tokens only
|
|
And every state is drawn in light and dark at 1440x900 and 390x844
|
|
And no state is date dependent
|
|
|
|
Rule: Section index and Jump to
|
|
|
|
Scenario: Index order
|
|
Given the viewport is 1440x900
|
|
Then the sticky index lists, in this order:
|
|
| Authentication | Articles | Search and sharing | Content types | Entries | Built-in types | Media |
|
|
| Sites and authors | Images and variants | Users and invites | Settings | Session only | Errors | Notes |
|
|
And on 390x844 the "Jump to" list shows the same items in the same order
|
|
|
|
Scenario: Scroll-spy on Content types (state 9j)
|
|
Given the Content types group is the section nearest the top of the page
|
|
Then its index item has aria-current "true" and the 2 px --ui-primary bar
|
|
And on mobile the "Jump to" select reads "Content types" and its open list marks that item
|
|
|
|
Rule: Endpoint groups
|
|
|
|
Scenario Outline: Group contents
|
|
Then the group "<group>" shows "<count>" with these routes and access chips
|
|
Examples:
|
|
| group | count | routes |
|
|
| Articles | 8 routes | unchanged (the 7 article routes and POST /v1/article/{id}/seo/check) |
|
|
| Search and sharing | 2 routes | unchanged |
|
|
| Content types | 5 routes | GET /v1/content-type/ and GET /v1/content-type/{key} Verified user; POST /v1/content-type/, PUT and DELETE /v1/content-type/{key} Owner or admin |
|
|
| Entries | 5 routes | GET and POST /v1/content-type/{key}/entry; GET, PUT and DELETE /v1/content-type/{key}/entry/{id}, all Verified user |
|
|
| Built-in types | 2 routes | GET /v1/builtin-type/ and GET /v1/builtin-type/{key}, Owner or admin |
|
|
| Media | 11 routes | the 7 existing (including GET /v1/media/{id}); GET and PATCH /v1/media/purge-settings, GET /v1/media/purge-preview, POST /v1/media/purge, Owner or admin |
|
|
| Sites and authors | 2 routes | GET /v1/site/ and GET /v1/author/, Verified user (the former Sites and Authors groups, merged) |
|
|
| Users and invites | 6 routes | unchanged |
|
|
| Settings | 1 route | unchanged |
|
|
And every route of these groups carries the chip "API key OK"
|
|
And the new groups appear in the order of the index
|
|
|
|
Scenario: Group descriptions
|
|
Then "Content types" reads "Define your own kind of content, like events or recipes. An owner or admin creates a type made of 1 to 50 ordered fields; the type then has its own entry routes."
|
|
And "Entries" reads "Read and write the content of a custom type. Any verified user can write entries."
|
|
And "Built-in types" says they are read-only through the API and that the keys are article, author, site, media and user
|
|
|
|
Scenario: Field types reference above the Content types routes
|
|
Then an anchor "ct-fields" sits above the first Content types route and is not an index item
|
|
And a "Field types" table with columns Type, Value in an entry and Rules lists text, richtext, number, boolean, date, select, media and relation
|
|
And a sample field object shows key capacity, label Capacity, type number, required true, unique false, default null, min 1, max 5000, options null, relation null
|
|
|
|
Scenario: PUT badge
|
|
Then the PUT method badge uses the PATCH colours
|
|
|
|
Scenario Outline: Expanded cards show their request fields and errors (states 9a and 9c)
|
|
When I expand "<route>"
|
|
Then the request table or query table shows "<fields>"
|
|
And the Errors list shows "<errors>"
|
|
Examples:
|
|
| route | fields | errors |
|
|
| POST /v1/content-type/ | key, name, icon, fields | 400, 401, 403 "Only owners and admins can do this.", 409 content_type_key_taken |
|
|
| PUT /v1/content-type/{key} | name, icon, fields | 400, 401, 403, 404 content_type_not_found, 409 schema_incompatible |
|
|
| DELETE /v1/content-type/{key} | No request body. | 401, 403, 404 content_type_not_found, 409 content_type_has_entries, 409 content_type_referenced |
|
|
| GET /v1/content-type/{key}/entry | page, size (5, 25, 50 or 100), sort (id, created_at or updated_at, then :asc or :desc) | 400 "Invalid page, size or sort.", 401, 404 content_type_not_found |
|
|
| POST /v1/content-type/{key}/entry | data | 400, 401, 404 content_type_not_found, 409 invalid_entry: title must be unique, 422 invalid_entry: capacity must be at most 5000 |
|
|
| GET /v1/content-type/{key}/entry/{id} | No request body. | 400 "The server expects the ID to be in the format of an unsigned 32-bit integer (uint32).", 401, 404 entry_not_found, 404 content_type_not_found |
|
|
| PUT /v1/content-type/{key}/entry/{id} | data | 400, 401, 404 entry_not_found, 404 content_type_not_found, 409 and 422 invalid_entry: <reason> |
|
|
| GET /v1/builtin-type/{key} | No request body. | 401, 403, 404 builtin_type_not_found |
|
|
And code-style captions show the literal body
|
|
|
|
Scenario: Response samples follow the real API
|
|
Then POST cards show only the JSON body, with no status line
|
|
And the entries list Response is an object with items, total, page and size, not a bare array
|
|
And an entry sample has id, content_type, data, created_by, updated_by, created_at, updated_at, media and relations
|
|
And the entry media sample is keyed by the field key, for example cover
|
|
And a built-in type sample has only key, name and fields, with no icon
|
|
And 409 on an entry only happens when a unique field clashes; any other field error is 422
|
|
|
|
Scenario: GET /v1/media/ is paginated
|
|
When I expand "GET /v1/media/"
|
|
Then a "Query parameters" table lists page and size (5, 25, 50 or 100, default 25) next to q, hash, filter, sort and variants
|
|
And the Response is an object with items, total, page, size and counts
|
|
And the Errors list has a 400 row "The media query is invalid."
|
|
|
|
Scenario: Media purge routes
|
|
Then GET and PATCH /v1/media/purge-settings use the keys auto_purge_enabled, auto_purge_interval_days (1 to 365), last_purge_at and last_purge_merged
|
|
And POST /v1/media/purge takes an optional fingerprint taken from purge-preview
|
|
And its Response sample has exactly groups_total, groups_purged, merged, articles_updated, sites_updated, authors_updated and failed_groups
|
|
And its description says failed_groups counts groups that could not be purged and the others were still purged
|
|
And no sample uses articlesUpdated or count for the purge response
|
|
|
|
Scenario: Sites and authors lists
|
|
Then GET /v1/site/ lists sites
|
|
And GET /v1/author/ has Query parameters page and size and returns an object with items, total, page and size
|
|
|
|
Rule: Session only
|
|
|
|
Scenario: Thirty-seven routes in six sub-groups (state 9e)
|
|
Then the heading reads "Session only" and the count reads "37 routes, not available to API keys", derived from the data
|
|
And the sub-groups are, in order: "System · owner only", "Sign in and account", "API key management", "Sites and authors writes", "Image variants", "Activity"
|
|
And every /v1/system route is in "System · owner only", with PATCH /v1/settings
|
|
And "Sign in and account" holds DELETE /v1/auth/register
|
|
And each row is dashed, muted and cannot expand
|
|
And each row that answers 403 to a key has the lock icon and the "Session only" chip; Log in, Log out, Register and Reset password keep their caption "Made for the browser. A key is ignored here, with no 403." and no chip
|
|
And the banner is unchanged
|
|
|
|
Rule: Errors table (state 9d)
|
|
|
|
Scenario: Rows and copy
|
|
Then the table has rows 400, 401, 403, 404, 409, 422, 429 and 500
|
|
And the 403 row lists "This action needs a real session.", "Only owners and admins can do this.", "Only the owner can do this." and "You must verify your account to access this resource."
|
|
And the 403 row keeps its muted note about site SEO defaults
|
|
And the 404 row adds content_type_not_found, entry_not_found and builtin_type_not_found
|
|
And the 409 row lists content_type_key_taken, content_type_has_entries, content_type_referenced, schema_incompatible, a unique-value clash and the existing media and user examples
|
|
And the 422 row lists "invalid_entry: <reason>"
|
|
And a note says code-style text is the literal body
|
|
And the old sentence saying there is no 409 or 422 row is gone
|
|
|
|
Rule: Authentication copy
|
|
|
|
Scenario: Key rights
|
|
Then the API key card says requests act as the user who created the key, with that user's role
|
|
And the page says a key can manage articles, media and users, and manage content types and entries, without the back-office
|
|
And Note 1 gains the sentence "Owner and admin routes answer 403 to a key whose creator is neither."
|
|
And the other authentication notes are unchanged
|
|
|
|
Rule: Search covers the new routes
|
|
|
|
Scenario: Index content
|
|
Then the search index holds 85 endpoints: 42 documented, 37 session-only and 6 public auth
|
|
And it includes the new endpoints, their body fields and query parameters, the events sample keys under data (title, starts_on, capacity, online, category, cover) as "Body field", and the new error codes and messages
|
|
|
|
Scenario Outline: Queries and counts
|
|
When I type "<query>" in the palette
|
|
Then the count and live region read "<announced>"
|
|
And the notes are "<notes>"
|
|
Examples:
|
|
| query | announced | notes |
|
|
| media | 17 results, showing 7 | Section Media reads "11 routes" |
|
|
| 404 | 24 results, showing 7 | rows show an "Error" second line |
|
|
| login | 2 results | Session only section reads "37 routes, not available to API keys" |
|
|
| entry | 8 results, showing 7 | also matches "entries" |
|
|
| capacity | 2 results | second line "Body field capacity" on POST and PUT entry |
|
|
| schema_incompatible | 1 result | second line "Error" on PUT /v1/content-type/{key} |
|
|
| content type | 12 results, showing 8 | Sections group lists Content types and Entries |
|
|
|
|
Scenario: Cap line is singular for one
|
|
Given exactly one endpoint is beyond the cap
|
|
Then the line reads "1 more endpoint. Keep typing to narrow the list."
|
|
And with several it reads "N more endpoints. Keep typing to narrow the list."
|
|
|
|
Scenario: Selecting a new endpoint
|
|
When I select PUT /v1/content-type/{key}
|
|
Then the palette closes, the card is scrolled to, expanded and focused, and flashes for 1.5 s
|
|
And the URL hash is #ep-ct-update
|
|
And the index and "Jump to" read "Content types"
|
|
|
|
Rule: Existing states stay
|
|
|
|
Scenario: Unchanged behaviour
|
|
Then states 1 to 7, 8a to 8h, the Images and variants section and the "Manage API keys" link behave as before
|
|
And figures in the existing specs (media routes, result counts, session-only count, the 409 and 422 sentence) are corrected to this feature
|