Files
RenewCMS/features/public_article_listing.feature
T

65 lines
3.8 KiB
Gherkin

Feature: Public and authenticated article listing
As a visitor of the public site and as an authenticated RenewCMS user
I want GET /v1/article/ to return every online article to anyone,
and every article, including offline ones, to a caller with a valid jwt cookie
So that the public site never displays a draft, while an authenticated user managing
the CMS can see and act on articles that are not published yet
Background:
Given internal/domain/article.Article has a json "is_online" field
And ListArticlesUseCase.ListOnlineArticles filters article.Filters{IsOnline: true} and
ListArticlesUseCase.ListAllArticles applies no filter, both already implemented
And before this slice, GET /v1/article/ sits inside the jwtauth Verifier + Authenticator group
in api/router.go along with GET /v1/article/{id}, POST /v1/article/ and DELETE /v1/article/{id},
so an anonymous request to any of them answers 401, not an online-only list
And this slice moves GET /v1/article/ under jwtauth.Verifier only, so a missing or invalid jwt
cookie no longer blocks the request; GET /v1/article/{id}, POST /v1/article/ and
DELETE /v1/article/{id} keep requiring jwtauth.Verifier + Authenticator, unchanged
And Handler.ListArticles decides between ListAllArticles and ListOnlineArticles by checking the
request for a valid jwt, read with jwtauth.FromContext from the token the router-level
jwtauth.Verifier (header and cookie sources) placed in the request context, rather than
requiring the router-level Authenticator middleware; article.NewHandler takes no token
And the response body is the JSON array article.Article marshals to, each element carrying its
own "is_online" value
Scenario: An anonymous visitor only sees online articles
Given the article repository contains an online article titled "Backyard Renovation Update" with id 1
And the same repository contains an offline article titled "Draft: Kitchen Remodel" with id 2
When the client sends GET /v1/article/ with no jwt cookie
Then the response status is 200
And the response body is a JSON array containing exactly the article with id 1
And the article with id 2 is absent from the response body
Scenario: An authenticated user sees every article, online and offline
Given a valid jwt cookie for a user with id 1
And the article repository contains an online article titled "Backyard Renovation Update" with id 1
And the same repository contains an offline article titled "Draft: Kitchen Remodel" with id 2
When the client sends GET /v1/article/ with that cookie
Then the response status is 200
And the response body is a JSON array containing both the article with id 1 and the article with id 2
Scenario: A malformed or expired jwt cookie falls back to the public online-only list
Given a jwt cookie whose value is not a token issued by JWT_SECRET
And the article repository contains an online article with id 1 and an offline article with id 2
When the client sends GET /v1/article/ with that cookie
Then the response status is 200
And the response body is a JSON array containing exactly the article with id 1
Scenario Outline: The rest of the article routes still require authentication
Given no jwt cookie is sent
When the client sends <method> <path>
Then the response status is 401
Examples:
| method | path |
| GET | /v1/article/1 |
| POST | /v1/article/ |
| DELETE | /v1/article/1 |
Scenario: A repository failure still answers 500 regardless of auth state
Given the article repository fails on its next call to FindByFilters
When the client sends GET /v1/article/ with no jwt cookie
Then the response status is 500
And the response body is the text "Failed to retrieve articles"