81 lines
4.3 KiB
Gherkin
81 lines
4.3 KiB
Gherkin
Feature: Domain not-found errors instead of raw GORM errors
|
|
|
|
As the maintainer of RenewCMS
|
|
I want a missing article or user reported as a domain not-found error
|
|
So that the API answers 404 for it instead of leaking a raw GORM error as a 500, and so that
|
|
a caller can rely on errors.Is(err, article.ErrArticleNotFound) or errors.Is(err, user.ErrUserNotFound)
|
|
|
|
Background:
|
|
Given internal/domain/article defines the sentinel article.ErrArticleNotFound
|
|
And internal/domain/user defines the sentinel user.ErrUserNotFound
|
|
And ArticleRepository.Get and ArticleRepository.GetByName return article.ErrArticleNotFound, not gorm.ErrRecordNotFound, when no row matches
|
|
And UserRepository.Get, UserRepository.GetByUsername and UserRepository.GetByEmail return user.ErrUserNotFound, not gorm.ErrRecordNotFound, when no row matches
|
|
And GET /v1/article/{id} sits behind the jwtauth Verifier and Authenticator group, and requires a valid jwt cookie
|
|
And a later slice, features/public_article_read.feature, moves GET /v1/article/{id} into the
|
|
Verifier-only group and makes it return an offline article to a verified caller instead of
|
|
404, mirroring the listing endpoint's visibility rule; the two scenarios below that depended
|
|
on the older, stricter rule are updated accordingly
|
|
|
|
Scenario Outline: The article repository reports a missing article as a domain error
|
|
Given a repository backed by an in-memory SQLite database containing an article titled "Backyard Renovation Update" with id 1
|
|
When <method> is called with <input>
|
|
Then the result is the error article.ErrArticleNotFound
|
|
And errors.Is(err, gorm.ErrRecordNotFound) is false
|
|
|
|
Examples:
|
|
| method | input |
|
|
| Get | id 9 |
|
|
| GetByName | "Unknown Title" |
|
|
|
|
Scenario Outline: The user repository reports a missing user as a domain error
|
|
Given a repository backed by an in-memory SQLite database containing a user with id 1, username "alice" and email "alice@example.com"
|
|
When <method> is called with <input>
|
|
Then the result is the error user.ErrUserNotFound
|
|
And errors.Is(err, gorm.ErrRecordNotFound) is false
|
|
|
|
Examples:
|
|
| method | input |
|
|
| Get | id 9 |
|
|
| GetByUsername | "bob" |
|
|
| GetByEmail | "bob@example.com" |
|
|
|
|
Scenario: Fetching a nonexistent article answers 404, not 500
|
|
Given a valid jwt cookie for a user with id 1
|
|
And the article repository has no article with id 9999
|
|
When the client sends GET /v1/article/9999 with that cookie
|
|
Then the response status is 404
|
|
And the response body is the text "Article not found"
|
|
|
|
Scenario: Fetching an offline article as an anonymous or unverified caller still answers 404 with the same message
|
|
Given no jwt cookie is sent
|
|
And the article repository contains an article with id 2, is_online false
|
|
When the client sends GET /v1/article/2 without a cookie
|
|
Then the response status is 404
|
|
And the response body is the text "Article not found"
|
|
|
|
Scenario: Fetching an online article still answers 200
|
|
Given a valid jwt cookie for a user with id 1
|
|
And the article repository contains an article with id 1, is_online true
|
|
When the client sends GET /v1/article/1 with that cookie
|
|
Then the response status is 200
|
|
And the response body is the article's JSON representation
|
|
|
|
Scenario: An unknown article id answers 404 even without authentication
|
|
Given no jwt cookie is sent
|
|
And the article repository has no article with id 9999
|
|
When the client sends GET /v1/article/9999 without a cookie
|
|
Then the response status is 404
|
|
And the response body is the text "Article not found"
|
|
|
|
Scenario Outline: Login never reveals whether the username exists
|
|
Given a user repository containing a user "alice" with password "hunter2example"
|
|
When the client sends POST /v1/auth/login with username "<username>" and password "<password>"
|
|
Then the response status is 403
|
|
And the response body is the text apperr.LogsErrorMessage
|
|
And no jwt cookie is set
|
|
|
|
Examples:
|
|
| username | password | case |
|
|
| alice | wrongpassword12 | existing user, bad pass |
|
|
| bob | hunter2example | unknown username |
|