5.3 KiB
5.3 KiB
QA procedure: public_article_read
Package: test (black-box, extending article_test.go, verified_account_required_http_test.go
and not_found_errors_test.go).
Setup shared by every case
- Call
validator.InitValidator()once. - Reuse
mockArticleRepo(test/article_test.go) andmockUserRepo(test/verified_account_required_http_test.go) as-is; no fake changes expected. - Wire the real use cases over the fakes:
useCases.NewGetArticleUseCase,useCases.NewGetUserUseCase, plusNewCreateArticleUseCase/NewListArticlesUseCase/NewDeleteArticleUseCase/NewUpdateArticleUseCasefor the regression routes. Buildarticle.NewHandler(create, get, list, delete, update, getUser). - Build a test
jwtauth.New("HS256", []byte("test-secret"), nil). - Mount routes on a fresh
chi.NewRouter()mirroring the amendedapi/router.goshape:r.Route("/v1", func(r chi.Router) { r.Route("/article", func(r chi.Router) { ... }) })r.Use(jwtauth.Verifier(token))on the whole/articlegroupr.Get("/", articleHandler.ListArticles)andr.Get("/{id}", articleHandler.GetArticle)directly under that Verifier-only group- a nested
r.Groupaddingjwtauth.Authenticator(token)thenmiddleware.RequireVerifiedUser(getUserUseCase), containingr.Post("/", ...),r.Delete("/{id}", ...),r.Patch("/{id}", ...),r.Patch("/{id}/publish", ...),r.Patch("/{id}/unpublish", ...)No live server.
- Mint a valid jwt cookie for user id 1 via
token.Encode(map[string]any{"user_id": uint32(1)}). - Seed the article repo directly, e.g.
repo.articles[1] = article.Article{ID: 1, Title: "Backyard Renovation Update", IsOnline: true}andrepo.articles[2] = article.Article{ID: 2, Title: "Draft: Kitchen Remodel", IsOnline: false}. - Seed the user repo with
repo.users[1] = user.User{ID: 1, IsVerified: <true|false>}as each case needs.
HTTP checks
GET /v1/article/1(online), no cookie -> 200, decode body, assertid == 1.GET /v1/article/2(offline), no cookie -> 404, body"Article not found\n".GET /v1/article/9999(no article with that id), no cookie -> 404, body"Article not found\n".GET /v1/article/2, cookie for user 1 withIsVerified: true-> 200, decode body, assertid == 2.GET /v1/article/1, cookie for user 1 withIsVerified: true-> 200,id == 1.GET /v1/article/9999, cookie for user 1 withIsVerified: true-> 404, body"Article not found\n".GET /v1/article/2, cookie for user 1 withIsVerified: false-> 404, body"Article not found\n"(never 403).GET /v1/article/1andGET /v1/article/2, cookie namedjwtwhose value is an arbitrary non-token string (e.g."not-a-real-token") -> 200 for id 1, 404 for id 2 (same as step 9/10, proving the invalid cookie falls back to public visibility).GET /v1/article/not-a-number, no cookie -> 400, bodyapperr.IdUint32ErrorMessage + "\n".- Regression, no cookie:
POST /v1/article/-> 401;DELETE /v1/article/1-> 401;PATCH /v1/article/1-> 401;PATCH /v1/article/1/publish-> 401;PATCH /v1/article/1/unpublish-> 401. - Configure the fake repo's
failSwitchso the nextGetcall returnserrRepositoryFailure(failNext("Get")).GET /v1/article/1with no cookie -> 500, body"Internal server error\n".
Required amendments to existing tests/specs (part of this slice, not optional cleanup)
test/verified_account_required_http_test.go: mover.Get("/{id}", articleHandler.GetArticle)innewVerifiedAccountRequiredRouterout of theAuthenticator+RequireVerifiedUsergroup into the outer Verifier-only group (mirroring step 5 above); remove the{http.MethodGet, "/v1/article/1", ""}row fromprotectedRouteCasesand the{http.MethodGet, "/v1/article/1"}row fromnoCookieCasesinTestVerifiedAccountRequiredHttp, since that route no longer produces 403 or 401.test/not_found_errors_test.go: mover.Get("/{id}", articleHandler.GetArticle)innewNotFoundErrorsRouterthe same way; change the"Fetching an offline article still answers 404 with the same message"subtest to use an unverified or anonymous caller (it currently usesnewVerifiedUserRepo(), which will now 200 instead of 404); replace"The article route still requires authentication before existence is even checked"with an assertion that an anonymous request for an unknown id now answers 404 (covered by step 11 above, so this subtest can instead be deleted in favor of the new test file, or repurposed to checkGET /v1/article/1with no cookie still answers 200 as a cross-file regression note).features/verified_account_required.featureandfeatures/not_found_errors.featureget the corresponding Examples-table/scenario edits described in this feature's Background.
Manual verification (not exercised by the Go test)
- SPA-visible behaviour: confirm the public front-office single-article view (unauthenticated) can
open a published article and 404s on a draft URL, and the authenticated back-office view can open
its own unpublished draft for editing, against the real embedded frontend and a real SQLite file.
Not exercised by
task test; requirestask devor a builttask buildbinary. - No SMTP involvement.