47 lines
4.8 KiB
Markdown
47 lines
4.8 KiB
Markdown
# QA procedure: article_body_format
|
|
|
|
Package: `test` (black-box). New files: `test/article_body_format_test.go`, `test/markdown_converter_test.go`, `test/json_blocks_converter_test.go`. No live server, no real SQLite file, no real SMTP.
|
|
|
|
## Setup
|
|
1. Call `validator.InitValidator()` once.
|
|
2. Reuse `mockArticleRepo` and `mockUserRepo`. Add a fake `fakeBodyRenderer` with a unique type name. It records each call's format and the html it received. For markdown it returns "MD:"+html. For html it returns the html unchanged. For json it returns `[{"type":"paragraph","children":[{"type":"text","text":"FAKE","marks":[]}]}]`. It has a failure switch.
|
|
3. Wire the real use cases over the fakes, passing the renderer. Update every existing test that builds these use cases for the new constructor signatures. Build `article.NewHandler(...)`.
|
|
4. Mount a fresh `chi.NewRouter()` mirroring `api/router.go` for `/v1/article`: `jwtauth.Verifier` on the group, GET `/` and `/{id}` public, and `Authenticator` + `RequireCurrentToken` + `RequireVerifiedUser` for POST, DELETE and PATCH.
|
|
5. Mint a jwt cookie for user_id 1 with `token.Encode(map[string]any{"user_id": uint32(1)})`. Seed a verified user. Seed articles 1 (online) and 2 (offline).
|
|
|
|
## HTTP checks (fake renderer)
|
|
6. Single read matrix: for each of none, `?format=`, markdown, MarkDown, html, HTML, json, JSON, assert status 200, `body_format`, the renderer's recorded format and the stored HTML passed in. For json, decode `body` and assert it is a JSON array (not a string).
|
|
7. List with none, `?format=html` and `?format=json`: every element has the matching `body_format`.
|
|
8. `format=pdf`, `xml` and `md` on single, list and unknown-id paths return 400 with `apperr.ArticleBodyFormatErrorMessage + "\n"`. The renderer and the repo are not called.
|
|
9. `GET /v1/article/abc?format=pdf` returns 400 with `apperr.IdUint32ErrorMessage + "\n"`.
|
|
10. `?format=html&format=json` returns html.
|
|
11. `GET /v1/article/2?format=json` anonymous returns 404 `"Article not found\n"`.
|
|
12. Write-route matrix with a cookie (POST, PATCH, publish, unpublish, each with none, html and json where listed): assert status, `body_format`, and that the repo holds the HTML that was sent.
|
|
13. `PATCH /v1/article/1?format=pdf` and `POST /v1/article/?format=pdf` with a cookie return 400. The repo is unchanged and no article is created.
|
|
14. Authenticated `GET /v1/article/?format=json` includes articles 1 and 2.
|
|
15. Renderer failure switch, then `GET /v1/article/1` returns 500 `"Internal server error\n"`.
|
|
|
|
## Domain
|
|
16. `ParseBodyFormat`: "", markdown, MARKDOWN, html, Html, json, JSON are accepted (empty returns markdown). pdf, md and " html" return `errors.Is(err, ErrUnsupportedBodyFormat)`.
|
|
|
|
## Converter tests (real library, real Tiptap HTML samples)
|
|
17. `test/markdown_converter_test.go`: every row of the markdown fidelity table, plus a combined document (heading, paragraph with marks, list, image, code block, quote, hr). Assert exact output. For format html, assert the input comes back byte-identical.
|
|
17b. Alignment and escaping: every row of the alignment and plain-text tables, for markdown and json, in `test/markdown_converter_test.go` and `test/json_blocks_converter_test.go`. `test/body_converter_documents_test.go` covers the combined hostile document (no raw script, style, iframe or span leaks in markdown or json), its block types, and code block text extraction.
|
|
18. `test/json_blocks_converter_test.go`: every row of the json shapes table. Assert by unmarshalling both sides and comparing with deep equality. This also asserts `marks` is `[]` rather than null or absent, `ordered` is a bool, and code `language` is "" when absent. Also include a combined document with nested list, blockquote and an image inside a paragraph. Assert that script and style content never appears, and that no raw HTML survives in any output for any format except html.
|
|
19. `test/json_blocks_converter_test.go` also asserts that html "" produces `[]`, and that the output is a non-null JSON array.
|
|
|
|
## SPA (Vitest, `task test:web`)
|
|
20. Mock `/v1/article/12?format=html` and assert `EditorView` requests that URL and loads the HTML body into the draft.
|
|
21. Assert `useArticles.listArticles` requests `/v1/article/?format=html`.
|
|
22. Assert the `ArticleView` image count is computed from the HTML.
|
|
23. Assert `useArticleDraft.save` sends PATCH `/v1/article/{id}?format=html` with the JSON body.
|
|
24. Reported as NOT RUN if there is no runner. No visual check applies, because no visual change is expected.
|
|
|
|
## Docs
|
|
25. Check that a docs/api article read page, the IntegrationView snippets and a docs/releases note exist as described.
|
|
|
|
## Manual verification
|
|
- In the embedded SPA, edit and save an article against a real SQLite file and confirm the stored body is still HTML.
|
|
- `curl` the public list and a single article with no format, `?format=html` and `?format=json` against a built binary.
|
|
- No SMTP involvement.
|