4.9 KiB
4.9 KiB
QA procedure: write_not_found_errors
Package: test (black-box, extending article_test.go / user_test.go / image_test.go / not_found_errors_test.go).
Setup shared by every case
- Call
validator.InitValidator()once. - Update the in-memory fakes (
mockArticleRepo,mockUserRepo,mockImageRepointest/) so that:mockArticleRepo.UpdateBody,UpdateIsOnlineandAddImagereturnarticle.ErrArticleNotFound/image.ErrImageNotFound(per the missing id) instead ofgorm.ErrRecordNotFound;mockArticleRepo.Deletereturnsarticle.ErrArticleNotFoundwhen the id isn't in the map, instead of silently succeeding;mockUserRepo.UpdateVerificationStatus,UpdatePassword,UpdatePasswordResetCodereturnuser.ErrUserNotFoundinstead ofgorm.ErrRecordNotFound;mockUserRepo.Deletereturnsuser.ErrUserNotFoundwhen the id isn't in the map, instead of silently succeeding;mockImageRepo.Deletereturnsimage.ErrImageNotFoundinstead ofgorm.ErrRecordNotFound. No fake intest/should referencegorm.ErrRecordNotFound(or importgorm.io/gorm) after this slice, except where still needed to assert a real repository's behavior in a repository-level test.
- Wire the real use cases (
useCases.NewUpdateArticleUseCase,useCases.NewDeleteArticleUseCase,useCases.NewUpdateUserUseCase,useCases.NewDeleteUserUseCase,useCases.NewDeleteImageUseCase) over the fakes for the use-case-level checks. - Build
article.NewHandler(...)from the article use cases plus a testjwtauth.New("HS256", []byte("test-secret"), nil), and mount it under achi.NewRouter()group wrapped byjwtauth.Verifier(token)+jwtauth.Authenticator(token), mirroringapi/router.go. No live server.
Repository-level checks (real persistence repositories, in-memory SQLite, no HTTP)
Use the existing openInMemoryDb(t) helper from test/not_found_errors_test.go.
db.AutoMigrate(&models.Article{}, &models.Image{}). Build a realpersistence.NewArticleRepository(db)andpersistence.NewImageRepository(db). Seed one article (id 1) and one image (id 1) viaCreate.UpdateBody(9, "New body")→ asserterrors.Is(err, article.ErrArticleNotFound)true,errors.Is(err, gorm.ErrRecordNotFound)false.UpdateIsOnline(9, true)→ same assertions.Delete(9)→ same assertions. ThenDelete(1)on the seeded article → asserterr == niland a subsequentGet(1)returnsarticle.ErrArticleNotFound(the row is actually gone).AddImage(9, 1)(unknown article, known image) → asserterrors.Is(err, article.ErrArticleNotFound)true.AddImage(1, 9)(known article, unknown image) → asserterrors.Is(err, image.ErrImageNotFound)true,errors.Is(err, gorm.ErrRecordNotFound)false.
- On the same or a fresh in-memory DB,
db.AutoMigrate(&models.User{}). Build a realpersistence.NewUserRepository(db), seed a user id 1.UpdateVerificationStatus(9, true),UpdatePassword(9, "x"),UpdatePasswordResetCode(9, "y")→ each assertserrors.Is(err, user.ErrUserNotFound)true,errors.Is(err, gorm.ErrRecordNotFound)false.Delete(9)→ same assertions. ThenDelete(1)on the seeded user → asserterr == niland a subsequentGet(1)returnsuser.ErrUserNotFound.
db.AutoMigrate(&models.Image{}). Build a realpersistence.NewImageRepository(db), seed one image via direct DB insert (orCreatewith a fakeio.ReaderandUPLOAD_DIRpointed att.TempDir()).Delete(9)→ asserterrors.Is(err, image.ErrImageNotFound)true,errors.Is(err, gorm.ErrRecordNotFound)false.
Fake-level checks (mirrors the real repositories, package-internal, no HTTP)
- For each of
mockArticleRepo,mockUserRepo,mockImageRepo, call the write methods listed in step 2 against an id absent from the fake's map and assert they return the matching domain sentinel, nevergorm.ErrRecordNotFound.
HTTP checks (fakes, per the shared setup above) — DELETE /v1/article/{id} only
- Mint a valid jwt cookie for user id 1 (as in
not_found_errors_test.go, step 8 there). DELETE /v1/article/9999with that cookie, empty repo id 9999 → assert status404, body"Article not found\n".DELETE /v1/article/1with that cookie, repo seeded with an article id 1 → assert status204, and that the fake no longer holds id 1 afterward.DELETE /v1/article/9999with no cookie → assert status401(regression: jwtauth still gates the route).
Manual verification (not exercised by the Go test)
- None.
UpdateArticle,AddImage,UpdateUser,DeleteUser,CreateImageandDeleteImagehave no HTTP route today (not mounted inapi/router.go), so there is no SPA-visible behavior or manual HTTP check for them in this slice — only the repository/fake-level checks above apply. No SMTP involvement.