feat: site languages, setup and site URL settings
This commit is contained in:
1 parent
0806733d5c
commit
d9158025d4
106 files changed
+10184
-56
No files matched your search
@@ -0,0 +1,61 @@
|
||||
# QA: Site languages (API and Languages page)
|
||||
|
||||
Accepted together with features/site_languages.feature. Backend: Go tests in test/, black-box. SPA: Vitest plus the visual gate.
|
||||
|
||||
## Automated, no server (task test)
|
||||
|
||||
1. Use cases over in-memory fakes of the language, site and article repositories (unique type names, shared package). Table-driven over "Rules that reject a change", "Social locale format and language part", "Changing the set", "A stale revision" and "Sending the same state again". Assert the Err sentinels with errors.Is. Assert that the update, the count of versions per language and the revision comparison run inside the Transactor under the site-row lock.
|
||||
2. Revision digest: same rows give the same revision, any change of lang, default, enabled or social_locale gives another one, counts do not.
|
||||
3. HTTP: NewHandler over the use cases, a fresh chi.NewRouter mirroring api/router.go (GET open to any verified user, PUT behind require(role.KeySettingsManageSites)), validator.InitValidator(), httptest, a jwt cookie signed with a test authtoken secret. Cover read, 401, 403, 404, 400, 409, 422 and 200. Assert status and exact plain-text body for every error. Assert the JSON key set of the read.
|
||||
4. Regression: existing site tests (the site JSON gains public_url_pattern only in the public-url feature) and article tests untouched. The internal/domain/language package is unchanged (diff check).
|
||||
|
||||
## Automated, SQLite file (task test)
|
||||
|
||||
5. Migration: a slice 1 database gains site_languages.social_locale and sites.public_url_pattern. Existing rows are unchanged. A second Migrate changes nothing (sqlite_master and a row hash).
|
||||
6. PUT atomicity: inject a failing write on the third row; assert nothing changed. Assert language_in_use against a draft, an offline and an online article, and that a soft-deleted article does not count.
|
||||
7. Concurrency: N goroutines create articles while PUT changes the default. Assert every article has the default current at its lock and none has lang "". Retry SQLITE_BUSY and bound the retries.
|
||||
|
||||
## Automated, real databases (task test:mysql, task test:postgres)
|
||||
|
||||
8. One targeted run of steps 5 to 7 (columns, PUT atomicity, version count) on MySQL 8.4, MariaDB 11 and PostgreSQL. The setup transaction is covered by the language_setup QA. Record NOT RUN if the daemon is down, or use the podman shim.
|
||||
|
||||
## Automated (Vitest + Vue Test Utils, task test:web)
|
||||
|
||||
Mock /v1 per case. Do not freeze the system date.
|
||||
9. One spec per row of "Page states", "Add a language", "Row actions" and "Social locale". Assert the exact copy, the accessible names ("Edit social locale for French", "Actions for French"), the request body of each PUT (full state, the revision from the last GET, social_locale null for an empty field) and that blocked states send no request.
|
||||
10. Mock set: GET 200 for Journal, Atelier and Archive (counts from the board fixtures), GET 5xx, PUT 200, PUT 500, PUT 409 languages_changed, PUT 409 language_in_use, PUT 422 invalid_social_locale.
|
||||
11. Route guard: a reader reaches the page and sees no controls; an anonymous visitor is redirected to login.
|
||||
12. SitesView: each row has "Languages" and "Public URL" actions with the right targets, for owners.
|
||||
13. Add dialog: a disabled language is listed "Disabled — re-enable instead" and cannot be added. Row menu items are Make default, Disable, Remove; Re-enable is a row button.
|
||||
14. i18n en/fr parity for every new key.
|
||||
15. task test:web, the type check, bun lint, and a diff check for comments.
|
||||
|
||||
## Visual (task visual:check -- localization-site-languages, hard gate at 10 %)
|
||||
|
||||
16. Run once at the end of the slice (group L1, 25 states). Desktop 1440 and mobile 390, light and dark. 1024 for loc.l1.multi and loc.l1.social. Reuse the board fixtures: Journal (4 enabled, es and it disabled), Atelier (social locale), Archive (single), counts from locale-fixtures.js. The board's it, ja and zh-Hans are mocks only.
|
||||
17. Known risk: the mobile rows are taller than needed (localization-corrections.md); tune in implementation, never raise the threshold.
|
||||
18. Not checked visually (no frame): setup banner, row menu, disabled language in the picker, SitesView row actions.
|
||||
|
||||
## Assumptions recorded for gaps without a frame
|
||||
|
||||
- Setup banner: presence and target only, copy pending the designer.
|
||||
- Row menu: Make default, Disable, Remove.
|
||||
- Disabled language in the picker: "Disabled — re-enable instead".
|
||||
- Version counts are visible to every signed-in reader; the exception is recorded in docs/.
|
||||
- Social locale rule 3 (Site.Locale language part) is deferred to slice 6.
|
||||
|
||||
## Fix round additions
|
||||
|
||||
- Soft-deleted version keeps the language in use: test/localization_fix_http_test.go (TestLanguageInUseCountsSoftDeletedVersions) and the sqlite persistence case.
|
||||
- Lock contention to 409: TestLanguageLockContention, TestDriverLockContention, TestTransactorClassifiesLockContention.
|
||||
- SQLite concurrency: TestLanguageConcurrencyOnSQLite (docs/api/site-languages.md explains why FOR UPDATE is a no-op there).
|
||||
- Activity: TestLanguageActivity.
|
||||
|
||||
## Manual
|
||||
|
||||
- Keyboard order and focus return in dialogs and the row menu; Escape closes; Tab order on mobile (44 px targets).
|
||||
- Dialog motion, hover and reduced-motion.
|
||||
- Two owners editing at once, in two browsers: the second sees "Languages changed. Reload."
|
||||
- Intl.DisplayNames names (for example "Portuguese (Brazil)") in en and fr.
|
||||
- docs/ gains the HTTP contract (shapes and codes above) and the accepted visibility exception for the next SPA slices.
|
||||
- task mutate scoped with MUTATE_FILES to the new use cases.
|
||||
Reference in new issue
Block a user