3.7 KiB
3.7 KiB
QA procedure: public_article_listing
Package: test (black-box, extending article_test.go).
Setup shared by every case
- Call
validator.InitValidator()once. - Reuse
mockArticleRepo(test/article_test.go) as-is;FindByFiltersand thefailSwitchalready support everything this slice needs, no fake changes expected. - Wire the real use cases over the fake:
useCases.NewCreateArticleUseCase,useCases.NewGetArticleUseCase,useCases.NewListArticlesUseCase,useCases.NewDeleteArticleUseCase. Buildarticle.NewHandler(create, get, list, delete). - Build a test
jwtauth.New("HS256", []byte("test-secret"), nil). - Mount the routes on a fresh
chi.NewRouter()mirroring the newapi/router.goshape:r.Route("/article", func(r chi.Router) { ... })r.Use(jwtauth.Verifier(token))on the whole/articlegroup (parses, never rejects)r.Get("/", articleHandler.ListArticles)directly under that Verifier-only group- a nested
r.Groupaddingjwtauth.Authenticator(token), containingr.Get("/{id}", articleHandler.GetArticle),r.Post("/", articleHandler.PostArticle),r.Delete("/{id}", articleHandler.DeleteArticle)No live server.
- Mint a valid jwt cookie for user id 1:
token.Encode(map[string]any{"user_id": uint32(1)}), set as thejwtcookie on the relevanthttptest.NewRequest. - Seed the repo for the listing cases via
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}(same direct-map pattern asTestGetOnlineArticle).
HTTP checks
GET /v1/article/with no cookie, repo seeded per step 7 -> status200; decode the JSON array and assert it has exactly one element, id1; assert no element has id2.GET /v1/article/with the valid cookie from step 6, same seed -> status200; decode the JSON array and assert it has exactly two elements, ids1and2both present.GET /v1/article/with a cookie namedjwtwhose value is an arbitrary non-token string (e.g."not-a-real-token"), same seed -> status200; assert the same single-element (id1) result as step 8, proving an invalid cookie falls back to the public list rather than erroring.GET /v1/article/1with no cookie -> status401(regression: single-article read still gated).POST /v1/article/with no cookie, JSON body{"title":"Valid Title","body":"Some content"}-> status401(regression: create still gated).DELETE /v1/article/1with no cookie -> status401(regression: delete still gated).- Configure the fake repo's
failSwitchso the nextFindByFilterscall returnserrRepositoryFailure(existingfailNext("FindByFilters")helper).GET /v1/article/with no cookie -> status500, body"Failed to retrieve articles\n". - As a regression on the valid-cookie path from step 9, also assert
GET /v1/article/{id}andPOST/DELETEstill succeed as before with a valid cookie (existing coverage inarticle_test.go/article_title_rules_test.go/write_not_found_errors_test.goalready covers this; no new assertions needed here beyond confirming the router restructuring didn't regress them -- rerun those suites as part oftask test).
Manual verification (not exercised by the Go test)
- SPA-visible behaviour: confirm the public front-office article list view (unauthenticated) only
renders online articles, and the authenticated back-office article list view renders offline
drafts too, against the real embedded frontend and a real SQLite file. Not exercised by
task test; requirestask devor a builttask buildbinary. - No SMTP involvement.