12 KiB
S6 — CI workflow + Manual QA Checklist
- Beads:
cp-la7(parent epiccp-cw4) - Depends on:
cp-i17(S5 — URL filters, закрыт) - Blocks:
cp-7cf(S7 — README + Gitea release + PUC) - Дата: 2026-05-16
Цель
Завершить тестовый этап MVP. Текущий 98-тестовый Brain Monkey suite уже покрывает 5 функциональных областей из изначального cp-la7 (Taxonomy, CPT, Shortcode, Router, Filters) на уровне call-signature через мок-фреймворк. Реальные WP integration tests с DB и WP-core checkout overkill для MVP и существенно overlap с unit-тестами.
S6 добавляет два artifact'а, которые закроют epic acceptance:
- Gitea Actions workflow — автоматический прогон phpunit на push/PR, готов к активации при mirror'е в Gitea (S7).
- Manual QA checklist — пошаговая ручная проверка против реального WP с ACF Pro, привязанная к acceptance criteria из cp-cw4.
И обновление README с инструкциями по тестированию.
Никаких новых PHP-классов, никаких новых phpunit-тестов. S6 — infrastructure-only.
Артефакты
wp-multi-city/
├── .gitea/workflows/test.yml # CREATE — CI workflow
├── docs/QA-CHECKLIST.md # CREATE — manual smoke checklist
└── README.md # MODIFY — Testing section + roadmap status
CI workflow — .gitea/workflows/test.yml
Gitea Actions syntax — subset of GitHub Actions, поддерживается с Gitea 1.19. Workflow срабатывает на push и pull_request:
name: tests
on:
push:
branches: [main]
pull_request:
jobs:
phpunit:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup PHP 8.0
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
coverage: none
tools: composer:v2
- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php8.0-${{ hashFiles('composer.json') }}
restore-keys: |
${{ runner.os }}-php8.0-
- name: Install dependencies
run: composer install --no-progress --prefer-dist --no-interaction
- name: Run PHPUnit
run: vendor/bin/phpunit
Файл лежит готовым; станет активным когда Gitea remote добавится в S7. До этого момента — placeholder без active CI.
PHP matrix (8.0/8.1/8.2/8.3), coverage report, lint job — отложено до S7+.
Manual QA checklist — docs/QA-CHECKLIST.md
Структура: 13 секций, каждая с шагами и expected outcome. Каждый чекпойнт — - [ ] для отметки. Привязка к acceptance criteria из cp-cw4 явная.
Шаблон секций
## N. <Имя секции>
**Cp-cw4 acceptance: <привязка>**
Preconditions: <состояние сайта>
Steps:
1. <шаг>
2. <шаг>
Expected:
- <критерий>
- <критерий>
- [ ] Section pass
Полные 13 секций
1. Plugin activation
- Preconditions: чистый WP 6.0+ с активированным ACF Pro.
- Steps: загрузить плагин в
wp-content/plugins/wp-multi-city/; активировать через admin → Plugins. - Expected: нет PHP-ошибок; нет admin notice "WP Multi City requires ACF Pro"; в admin menu появляются «Шорткоды», «WP Multi City».
2. ACF dependency notice
- Preconditions: WP с деактивированным ACF Pro.
- Steps: активировать плагин.
- Expected: admin notice "WP Multi City: требуется активный плагин Advanced Custom Fields Pro" виден; плагин не вешает хуки.
3. Admin UI — taxonomy town
- Preconditions: плагин активен, ACF Pro установлен.
- Steps: открыть admin → Шорткоды → Города.
- Expected: пустой список term'ов; кнопка «Добавить» работает; создать term
tyumenиspb.
4. Admin UI — CPT shortcode-town
- Preconditions: §3 завершён.
- Steps: открыть admin → Шорткоды → Добавить.
- Expected: edit-screen показывает поле title + ACF repeater «Подстановки по городам» (
list_shortcode) с двумя sub-fields «Город» и «Значение»; town sub-field — dropdown с термами spb/tyumen.
5. Admin UI — Options page
- Preconditions: §3 завершён.
- Steps: открыть admin → WP Multi City.
- Expected: ACF options page «WPMultiCity / Routing» с 4 полями: main_town_slug (dropdown town), index_town_alt (page picker), page_unic (repeater 3 sub-fields), page_no_rep (repeater 1 sub-field link).
6. Helper functions smoke
- Preconditions: §3 завершён, создана страница «About» (ID=10).
- Steps: в functions.php темы (или mu-plugin) вставить:
Открыть
add_action('wp_footer', function() { error_log('current_town: ' . var_export(wpmc_current_town(), true)); error_log('get_term: ' . var_export(wpmc_get_term_by_slug('tyumen'), true)); error_log('remove_domain_link: ' . wpmc_remove_domain_link('https://example.com/foo/')); });/tyumen/about/(или с любым term-slug в URL). - Expected: error log показывает
current_town: 'tyumen',get_term: WP_Term { term_id: ..., slug: 'tyumen' },remove_domain_link: '/foo/'. Открытие/:current_town=null(без main_town_slug в options).
7. [shortcode_dmr] resolves by town
- Preconditions: §3-4 завершено. Создан shortcode-town пост ID=42 с одной row: town=tyumen, text=«Тюмень-текст».
- Steps: создать страницу с content
[shortcode_dmr id=42]. Открыть на/tyumen/<page-slug>/. Открыть на/<page-slug>/. - Expected: на /tyumen/ — «Тюмень-текст»; на / — пусто (без main_town_slug).
8. Router patches $wp_query
- Preconditions: §3, §5 завершено. В Options Page выставлен main_town_slug=spb. Создана page «About» ID=10.
- Steps: открыть
/tyumen/about/. - Expected: контентом загружается страница About (через
$wp_query->page_id=10);get_query_var('town')в шаблоне ='tyumen'. Открыть/spb/about/— стандартный WP fallback (main town не патчится).
9. /{slug}/ root with main_page_alt
- Preconditions: §8 завершено. Создана страница «Главная Тюмень» ID=20. На term'е tyumen выставлен ACF field
main_page_alt= 20. - Steps: открыть
/tyumen/. - Expected: загружается page 20;
is_front_page()= true;get_queried_object()->ID= 20.
10. page_unic clone swap
- Preconditions: §8 завершено. Создана клон-страница «About-Tyumen» ID=21. В Options Page → page_unic добавлена row: page_old=10, page_new=21, town=tyumen.
- Steps: открыть
/tyumen/about/. - Expected: контентом загружается page 21 (клон), не 10 (оригинал); URL остаётся
/tyumen/about/.
11. URL filters — town prefix injection
- Preconditions: §8 завершено. Тема выводит menu (nav-menu) со ссылкой на
/uslugi/. - Steps: открыть
/tyumen/about/; inspect menu link; inspect ACF link field value (если есть). - Expected: menu link href =
/tyumen/uslugi/илиhttps://host/tyumen/uslugi/; ссылка на main town (/spb/uslugi/) не префиксится; внешние ссылки (https://other.com/) не префиксятся; mailto:/tel: не меняются; ссылки уже с городским префиксом (/tyumen/contact/) не получают double-prefix.
12. page_no_rep exclusions
- Preconditions: §8 завершено. В Options Page → page_no_rep добавлен
/privacy/. Создана страница Privacy ID=30. - Steps: открыть
/privacy/. - Expected: стандартный WP load page Privacy;
$wp_queryне патчится; ссылки на этой странице (по template) не префиксятся (is_routable_pathвозвращает false).
13. rest_url + REST API
- Preconditions: WP REST API доступен.
- Steps: в шаблоне
echo rest_url('wp/v2/posts'); обратиться к этому URL через curl или браузер. - Expected: URL возвращает
https://{HTTP_HOST}/wp-json/wp/v2/posts(не site_url); ответ — JSON список постов.
Финал чеклиста
В конце документа — раздел "Release sign-off":
## Release sign-off
- [ ] All 13 sections passed
- [ ] PHPUnit suite green (`vendor/bin/phpunit` → OK 98 tests, 175 assertions)
- [ ] PHP lint clean (`composer test-lint` или `find includes -name '*.php' -exec php -l {} \;`)
- [ ] Tested on WP 6.0+ with PHP 8.0+
- [ ] No PHP notices/warnings in error_log
Tester: ______________ Date: ______________ Plugin version: ______________
README — обновление
Добавить новую секцию «Testing» после раздела «Установка»:
## Testing
### Automated (PHPUnit)
```bash
composer install
vendor/bin/phpunit
Expected: 98 tests, 175 assertions green. Unit-level coverage via Brain Monkey + Mockery + Patchwork (no real WP required; runs in <1s).
Manual QA
For end-to-end verification against a real WordPress installation, see docs/QA-CHECKLIST.md. Run through the checklist before any release.
CI
.gitea/workflows/test.yml runs PHPUnit on every push and pull request. Active once the repo is mirrored to Gitea (S7).
Обновить roadmap-таблицу: пометить S6 как `done`:
| S6 | PHPUnit-тесты (бутстрап + integration) | cp-la7 | done |
## Acceptance verification
После всех 3 артефактов:
1. `.gitea/workflows/test.yml` — YAML валидный, проходит через `yamllint` (опционально).
2. `docs/QA-CHECKLIST.md` существует, 13 секций + sign-off, плюс прохождение хотя бы 1 секции в реальной среде для smoke (опционально).
3. README обновлён, roadmap-таблица показывает S6=done.
4. `vendor/bin/phpunit` всё ещё зелёный (98/175) — ни один из 3 артефактов не ломает существующий suite.
## Что НЕ входит в S6
- Реальные WP integration tests с DB и WP-core checkout (overlap с unit-тестами, overkill для MVP).
- Docker/wp-env runtime для тестов.
- PHP matrix в CI (8.0/8.1/8.2/8.3) — отложено до S7+.
- Code coverage reports (phpunit coverage) — отложено.
- `bin/smoke.php` wp-cli helper — отложено; manual checklist покрывает MVP.
- Lint job в CI (phpcs/phpstan) — отложено.
## Open questions
Нет. Все решения зафиксированы.