8 Commits

Author SHA1 Message Date
Vladimir Bryzgalov 4debe8287a wp-plugin-info.json: update for 1.2.1 2026-05-01 20:20:30 +05:00
Vladimir Bryzgalov 0cc1266912 release: 1.2.1 2026-05-01 20:20:29 +05:00
Vladimir Bryzgalov f510ac484a fix(cron): self-heal scheduled events on every boot + on plugin upgrade
Pilot on washanyanya.ru lost the cf7stg_dispatch cron event somewhere
between 21.04 and 01.05 — wp_next_scheduled('cf7stg_dispatch') returned
NULL, queue had 6 pending rows, sent-24h=0, failed=0, no error trail.
Settings/token were intact. The most likely cause is the PUC self-update
to 1.2.0: WordPress plugin upgrades replace files but do NOT call
register_activation_hook, so Activator::activate() never re-ran and any
cron event Activator::deactivate() had cleared (or that was lost for any
other reason) stayed missing.

Two-part fix:

1. Activator::ensure_scheduled() — extracted from the old private
   schedule_events(), now public and idempotent. wp_next_scheduled()
   short-circuits when events are already queued, so it's safe to call
   on every request. Plugin::boot() invokes it on plugins_loaded — every
   admin or front-end hit auto-heals lost cron events.

2. Activator::on_upgrade_complete() bound to upgrader_process_complete.
   When WordPress finishes upgrading THIS plugin (matched via
   plugin_basename + $hook_extra['plugins']), we re-run install_table()
   (idempotent dbDelta), seed_silent_drop_options() (uses add_option,
   preserves user values), and ensure_scheduled(). guard_requirements
   is intentionally skipped — wp_die mid-upgrade would leave admin in
   a broken state, and the host obviously meets requirements since the
   old version is currently running.

Tests untouched (this is integration code wrapping WP-only APIs); full
suite still 126/126 green.

Changelog entry for 1.2.1 added to readme.txt.
Stable tag and CF7STG_VERSION will be bumped by release.sh.

Refs: cp-1lg

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:19:34 +05:00
Vladimir Bryzgalov ad14d0e6e3 docs: add deploy-to-sites guide for juniors
Installing/updating the plugin on client sites. Covers the two scenarios
(first-time manual install vs. auto-update after 1.2.0), SSH/admin install
paths, smoke tests, and common troubleshooting.
2026-04-22 00:12:18 +05:00
Vladimir Bryzgalov 1fd330fa0e refactor(release): use pretty download_url from /releases/{id} API
Gitea's POST /releases/{id}/assets endpoint returns an internal
/attachments/<uuid> URL. GET /releases/{id} returns the pretty
/<owner>/<repo>/releases/download/<tag>/<name> URL for the same asset.

Both resolve to the same bytes (verified: 207949 for 1.2.0 zip).
Pretty URL is preferred: filename is visible in the URL (better for
WP admin «View version details» and manual downloads), consistent
across Gitea instances (UUID format is git.netranking.ru-specific
Postgres attachment storage).

Also: switch `echo "$VAR" | jq` to `jq ... <<< "$VAR"`
herestring for CREATE_RESPONSE parsing — macOS /bin/echo can
interpret backslash-escapes in multi-line JSON bodies and corrupt
jq input.

wp-plugin-info.json for 1.2.0 patched in-place to use the pretty URL
for consistency with future releases. Both URLs continue to work;
domработница.рус's next PUC poll will refresh its local transient
to the pretty URL (version comparison stays 1.2.0 == 1.2.0, so no
update notice).

Closes cf7stg-pmf (T20).
2026-04-22 00:08:49 +05:00
Vladimir Bryzgalov 79e46ccf7e fix(release): post-mortem fixes discovered during 1.2.0 release
Issue 1: `unzip -l "$ZIP_PATH" | grep -q ...` combined with set -o
pipefail silently fails when grep -q exits on first match and SIGPIPEs
the upstream unzip (which has not yet finished streaming the long file
list). pipefail sees unzip's non-zero exit and fails the pipeline, so
the guard thinks the file is missing. Fix: capture unzip -l output to
a variable once, then grep the string via herestring. The first two
sanity checks using `unzip -p` (short output, tight race window) were
not affected.

Issue 2: test_wp_plugin_info_json_download_url_contains_expected_asset_name
assumed Gitea asset URLs always contain the asset filename. This is
not true on git.netranking.ru, which returns /attachments/<uuid> — a
UUID-only URL. Relaxed the test to assert the URL is an HTTPS Gitea
URL; freshness of download_url is enforced indirectly via the
version-match test.

Post-mortem: 1.2.0 release was completed via a manual recovery script
after release.sh failed at the zip-sanity step. State on main is
consistent: tag v1.2.0 -> release commit, JSON commit directly on top
of release commit, JSON points to the live Gitea asset.
2026-04-21 23:55:16 +05:00
Vladimir Bryzgalov 1a15f0c872 wp-plugin-info.json: update for 1.2.0 2026-04-21 23:53:53 +05:00
Vladimir Bryzgalov b0fb5c8e3d release: 1.2.0 2026-04-21 23:50:23 +05:00
8 changed files with 290 additions and 48 deletions
+2 -2
View File
@@ -2,7 +2,7 @@
/**
* Plugin Name: CF7 Spam → Telegram
* Description: Пересылает spam-заявки Contact Form 7 в Telegram-группу с эвристической оценкой.
* Version: 1.1.0
* Version: 1.2.1
* Author: Vladimir Bryzgalov
* Requires PHP: 7.4
* Requires at least: 6.0
@@ -17,7 +17,7 @@ if (!defined('ABSPATH')) exit;
define('CF7STG_PLUGIN_FILE', __FILE__);
define('CF7STG_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CF7STG_PLUGIN_URL', plugin_dir_url(__FILE__));
define('CF7STG_VERSION', '1.1.0');
define('CF7STG_VERSION', '1.2.1');
require_once CF7STG_PLUGIN_DIR . 'includes/class-plugin.php';
\Cf7stg\Plugin::register_autoloader();
+162
View File
@@ -0,0 +1,162 @@
# Развёртывание CF7 Spam → Telegram на сайт
Инструкция для того, кто устанавливает/обновляет плагин на WP-сайтах клиентов.
Разработчик (я) выпускает новые версии через `release.sh` — тебе этот процесс трогать не нужно.
## Как вообще обновляется плагин
Есть два разных сценария:
### Сценарий A: сайт уже работает на версии 1.2.0 или новее
**Ничего делать не надо.** WordPress сам раз в 12 часов проверяет Gitea, и если появилась новая версия — показывает «Доступно обновление» в списке плагинов. Клиент (или ты) нажимает «Обновить» — и всё.
### Сценарий B: плагин ставится впервые, или на сайте версия старше 1.2.0
В этом случае **первый раз** нужно установить вручную (один раз). После этого сайт перейдёт в сценарий A и дальше обновляется сам.
---
## Как понять, в каком сценарии сайт
1. Зайди в админку сайта → «Плагины».
2. Найди строку «CF7 Spam → Telegram».
3. Посмотри версию справа от названия.
- **≥ 1.2.0** → сценарий A. Дальше не читай, просто жди когда WP покажет обновление, или нажми «Проверить обновления» сверху списка.
- **< 1.2.0** или плагина нет → сценарий B, читай ниже.
---
## Сценарий B: первая ручная установка / переход на 1.2.0+
### Шаг 1. Скачай свежий релиз
1. Открой https://git.netranking.ru/bryzgalov/cf7-spam-to-telegram/releases
2. В списке релизов возьми самый верхний (последняя версия).
3. В разделе **Downloads** этого релиза скачай файл `cf7-spam-to-telegram-X.Y.Z.zip` (где X.Y.Z — номер версии).
Никаких логинов на Gitea не нужно — репозиторий публичный.
### Шаг 2. Установи плагин на сайт
Есть два способа — выбирай тот, к которому есть доступ.
#### Способ 1 (проще) — через админку WordPress
1. Логин в админку сайта (данные — в корпоративном менеджере паролей / у разработчика).
2. Плагины → **Добавить новый** → кнопка **Загрузить плагин** сверху.
3. Выбери скачанный `cf7-spam-to-telegram-X.Y.Z.zip`**Установить**.
4. Если WordPress ругается «Плагин уже установлен» и предлагает заменить — соглашайся, нажимай **Заменить текущей версией**.
5. Активируй плагин (кнопка **Активировать**, если сам не активировался).
#### Способ 2 — через SSH / FTP (если в админку не пускает или хочется контроля)
1. Подключись по SSH к серверу.
2. Найди папку плагина: обычно `<корень-сайта>/wp-content/plugins/cf7-spam-to-telegram/`.
3. Переименуй старую папку в бэкап (на случай отката):
```bash
cd <путь-к-сайту>/wp-content/plugins
mv cf7-spam-to-telegram cf7-spam-to-telegram.bak-$(date +%s)
```
4. Загрузи скачанный zip на сервер (через `scp`, `rsync` или панель хостинга в домашнюю директорию).
5. Распакуй zip в `wp-content/plugins/`:
```bash
cd <путь-к-сайту>/wp-content/plugins
unzip ~/cf7-spam-to-telegram-X.Y.Z.zip
```
Должна появиться папка `cf7-spam-to-telegram/` рядом с бэкапом.
6. Проверь, что плагин подхватился: в админке WP → Плагины → должен висеть с новой версией и статусом «Активен» (если был активен до замены — останется активным).
### Шаг 3. Проверь, что ничего не сломалось
1. Админка → Настройки → **CF7 Spam → TG** (или похожий пункт меню).
2. Убедись, что заполнены **Bot Token** и **Chat ID**. После обновления они должны сохраниться — если пусто, это плохой знак, пиши разработчику.
3. Нажми **Отправить тестовое сообщение** — в Telegram-группе должно появиться тестовое сообщение.
4. Через 10–20 минут заполни тестовый спам на одной из форм Contact Form 7 сайта (любой бессмысленный текст в поле сообщения, невалидный email) — убедись, что сообщение пришло в TG.
### Шаг 4. (Только для Сценария B) Убедись, что автообновление теперь включено
После того как установлена версия 1.2.0 или выше, WP должен начать сам следить за обновлениями. Проверим это сразу, не ждать 12 часов:
1. Плагины → наверху страницы ссылка **Проверить обновления** (или аналогично) → нажать.
2. WordPress опросит Gitea. Если установленная версия совпадает с последней на Gitea — всё хорошо, обновлений нет (норма).
3. Если вдруг появилась плашка «Доступно обновление» — значит на Gitea уже есть более свежая версия (редкий случай: релиз вышел пока ты устанавливал). Нажми **Обновить**, всё должно пройти автоматически.
### Шаг 5. Зачисти бэкап (через 1-2 дня)
Если ты использовал Способ 2 (SSH) и создал папку `cf7-spam-to-telegram.bak-<timestamp>/` — оставь её на 1-2 дня на всякий случай. Если всё работает — удали:
```bash
rm -rf <путь-к-сайту>/wp-content/plugins/cf7-spam-to-telegram.bak-*
```
---
## Как работают автообновления (для понимания)
После установки 1.2.0+ в плагине есть библиотека [Plugin Update Checker v5.6](https://github.com/YahnisElsts/plugin-update-checker), которая:
1. Раз в 12 часов (или при нажатии «Проверить обновления») ходит по URL:
`https://git.netranking.ru/bryzgalov/cf7-spam-to-telegram/raw/branch/main/wp-plugin-info.json`
2. Сверяет версию в JSON с версией установленного плагина.
3. Если в JSON версия новее — показывает WP-админке «Доступно обновление».
4. Когда клиент нажимает «Обновить», WP скачивает zip по URL из поля `download_url` в JSON (это zip с Gitea релиза) и распаковывает поверх.
Поэтому сайт должен иметь исходящий HTTPS-доступ на `git.netranking.ru`. Большинство хостингов это не блокируют, но **Beget** (и некоторые российские shared-хостинги) иногда ограничивают исходящие соединения — если обновления не приходят, это первое, что надо проверить.
---
## Типовые проблемы
### «Сайт не видит обновление, хотя на Gitea новая версия есть»
1. Плагины → **Проверить обновления** — нажми принудительно.
2. Если всё равно не видит, зайди на сайт по SSH и открой:
`<путь-к-сайту>/wp-content/debug.log` (если он включён) или error.log хостинга.
Ищи строки со словами `plugin-update-checker`, `PucFactory`, `cf7stg`, `wp-plugin-info`. Пришли их мне.
3. Проверь, что сайт достучится до Gitea. На сервере:
```bash
curl -I https://git.netranking.ru/bryzgalov/cf7-spam-to-telegram/raw/branch/main/wp-plugin-info.json
```
Ожидается `HTTP/2 200`. Если `404` или `timeout` — хостинг блокирует исходящий HTTPS или не пускает на `git.netranking.ru`. Пиши мне.
### «При обновлении ошибка, плагин не активируется»
1. Если плагин реально сломался, откати через SSH:
```bash
cd <путь-к-сайту>/wp-content/plugins
rm -rf cf7-spam-to-telegram
mv cf7-spam-to-telegram.bak-<timestamp> cf7-spam-to-telegram
```
(Имя бэкап-папки увидишь через `ls`).
2. Если бэкапа нет (после автообновления — WP обычно не оставляет бэкап) — напиши мне, пришлю zip предыдущей версии вручную.
3. Проверь PHP-версию хостинга: плагин требует **PHP 7.4+**. Если PHP 7.3 или ниже — обновляй PHP на панели хостинга.
4. Плагин требует установленные **Contact Form 7** и **Flamingo**. Если их отключили — активация нашего плагина упадёт.
### «После обновления пропали настройки (Bot Token / Chat ID)»
Это не должно случиться — настройки хранятся в WP-опциях, а не в файлах плагина. Если всё-таки произошло, напиши мне сразу: возможно, активация сработала со сбоем. Временное решение — заново вбить токен и Chat ID из менеджера паролей и сохранить.
### «Я установил плагин руками, но в админке плашки про автообновление нет»
Это нормально: WP не пишет «теперь у меня есть автообновление». Плашка появится только когда реально **появится** новая версия на Gitea. Сейчас просто дождись (или попроси разработчика сделать тестовый релиз — он сможет выпустить, скажем, 1.2.1 с одним фиксом, чтобы ты проверил, что update приходит).
---
## Куда писать, если что-то не так
- Разработчик: **Владимир Брызгалов**, email `vladimir.bryzgalov@gmail.com` / Telegram (уточни у руководителя).
- Исходники плагина: https://git.netranking.ru/bryzgalov/cf7-spam-to-telegram
- Все релизы: https://git.netranking.ru/bryzgalov/cf7-spam-to-telegram/releases
При обращении приложи:
- Адрес сайта
- Версию WP, версию PHP (Админка → Инструменты → Здоровье сайта → Информация)
- Скрин ошибки или содержимое `error.log` за момент проблемы
- Что именно делал (шаг инструкции, на котором споткнулся)
+58 -17
View File
@@ -13,7 +13,7 @@ final class Activator
self::guard_requirements();
self::install_table();
self::seed_silent_drop_options();
self::schedule_events();
self::ensure_scheduled();
}
public static function deactivate(): void
@@ -22,6 +22,63 @@ final class Activator
wp_clear_scheduled_hook('cf7stg_cleanup');
}
/**
* Self-heal cron events. Idempotent — safe to call from Plugin::boot()
* on every request. If wp_next_scheduled() shows the hook isn't queued,
* re-schedule it. This recovers from any cause of cron loss (manual
* wp_clear_scheduled_hook, plugin upgrade that bypassed activation,
* truncated wp_options.cron value) without requiring deactivate/activate
* by the user.
*
* The cron_schedules filter must be in place inside this same request so
* 'cf7stg_every_minute' is a known recurrence at wp_schedule_event time.
* Dispatcher::register_hooks() also registers it on plugins_loaded, but
* we add it here too in case ensure_scheduled() runs from a context where
* Dispatcher's registration hasn't fired yet (e.g. during an upgrade hook).
*/
public static function ensure_scheduled(): void
{
add_filter('cron_schedules', ['\\Cf7stg\\Dispatcher', 'register_schedule']);
if (!wp_next_scheduled('cf7stg_dispatch')) {
wp_schedule_event(time() + 60, 'cf7stg_every_minute', 'cf7stg_dispatch');
}
if (!wp_next_scheduled('cf7stg_cleanup')) {
wp_schedule_event(time() + 3600, 'daily', 'cf7stg_cleanup');
}
}
/**
* upgrader_process_complete callback. WordPress fires this after a
* plugin / theme / core update completes. Plugin updates do NOT call
* register_activation_hook, so any cron events the user's old install
* relied on must be re-installed explicitly here. We also re-run the
* table installer (idempotent dbDelta) and re-seed silent-drop options
* (uses add_option, so user values are preserved).
*
* @param mixed $upgrader WP_Upgrader instance (unused).
* @param array $hook_extra ['action'=>'update','type'=>'plugin','plugins'=>[...]]
*/
public static function on_upgrade_complete($upgrader, $hook_extra): void
{
if (!is_array($hook_extra)) return;
if (($hook_extra['action'] ?? '') !== 'update') return;
if (($hook_extra['type'] ?? '') !== 'plugin') return;
$plugins = (array)($hook_extra['plugins'] ?? []);
$self = plugin_basename(CF7STG_PLUGIN_FILE);
if (!in_array($self, $plugins, true)) {
return;
}
// Skip guard_requirements() — already running on a live install whose
// PHP/WP versions are clearly compatible. wp_die here would interrupt
// the upgrader and leave admin in a broken state.
self::install_table();
self::seed_silent_drop_options();
self::ensure_scheduled();
}
private static function guard_requirements(): void
{
if (version_compare(PHP_VERSION, '7.4', '<')) {
@@ -86,20 +143,4 @@ final class Activator
]);
}
private static function schedule_events(): void
{
// Register the custom 60-second schedule here — Dispatcher::register_hooks()
// runs on plugins_loaded, which is AFTER activation. Without this filter
// being in place during activate(), wp_schedule_event with an unknown
// recurrence ('cf7stg_every_minute') silently fails and the event never
// fires.
add_filter('cron_schedules', ['\\Cf7stg\\Dispatcher', 'register_schedule']);
if (!wp_next_scheduled('cf7stg_dispatch')) {
wp_schedule_event(time() + 60, 'cf7stg_every_minute', 'cf7stg_dispatch');
}
if (!wp_next_scheduled('cf7stg_cleanup')) {
wp_schedule_event(time() + 3600, 'daily', 'cf7stg_cleanup');
}
}
}
+9
View File
@@ -50,6 +50,15 @@ final class Plugin
Dispatcher::register_hooks();
(new CF7Source())->register();
// Self-heal cron events on every boot. Recovers from PUC self-update
// (which doesn't run register_activation_hook) and any other cause of
// cron event loss. Idempotent — wp_next_scheduled() short-circuits
// when events are already queued.
Activator::ensure_scheduled();
// Re-run install steps after a plugin upgrade (PUC or wp-admin upload).
add_action('upgrader_process_complete', ['\\Cf7stg\\Activator', 'on_upgrade_complete'], 10, 2);
self::register_update_checker();
// Admin
+5 -1
View File
@@ -4,7 +4,7 @@ Tags: contact-form-7, telegram, spam, flamingo
Requires at least: 6.0
Tested up to: 6.9
Requires PHP: 7.4
Stable tag: 1.1.0
Stable tag: 1.2.1
License: GPLv2 or later
Пересылает в Telegram-группу submissions CF7, помеченные как спам, с эвристической оценкой «похоже клиент / неясно / похоже спам».
@@ -24,6 +24,10 @@ License: GPLv2 or later
== Changelog ==
= 1.2.1 =
* Fix: Cron-события `cf7stg_dispatch` / `cf7stg_cleanup` теперь самовосстанавливаются. `Plugin::boot()` на каждой загрузке вызывает `Activator::ensure_scheduled()` — если событие пропало (PUC self-update без `register_activation_hook`, ручной `wp_clear_scheduled_hook`, обрезанный wp_options.cron), оно немедленно пересоздаётся. До фикса очередь могла молча застревать на дни без признаков ошибки (sent-24h=0, failed=0).
* Fix: Подписан хук `upgrader_process_complete` — после plugin update WordPress повторно вызывает `Activator::install_table()`, `seed_silent_drop_options()` и `ensure_scheduled()`. Без guard_requirements (чтобы не убить admin при апгрейде).
= 1.2.0 =
* New: Self-hosted plugin updates from Gitea via Plugin Update Checker v5.6.
WordPress admin shows updates automatically (checked hourly). Source:
+26 -8
View File
@@ -129,14 +129,18 @@ unzip -p "$ZIP_PATH" cf7-spam-to-telegram/cf7-spam-to-telegram.php \
| grep -q "CF7STG_VERSION', '${VERSION}'" \
|| fail "zip sanity: CF7STG_VERSION mismatch inside $ZIP_PATH"
unzip -l "$ZIP_PATH" | grep -q "cf7-spam-to-telegram/includes/lib/plugin-update-checker/plugin-update-checker.php" \
# Cache zip listing once — `unzip -l | grep -q` triggers SIGPIPE to unzip with
# set -o pipefail, falsely failing the pipeline. Capture the list, then grep the string.
ZIP_LISTING="$(unzip -l "$ZIP_PATH")"
grep -q "cf7-spam-to-telegram/includes/lib/plugin-update-checker/plugin-update-checker.php" <<< "$ZIP_LISTING" \
|| fail "zip sanity: PUC loader missing from $ZIP_PATH"
unzip -l "$ZIP_PATH" | grep -q "cf7-spam-to-telegram/wp-plugin-info.json" \
grep -q "cf7-spam-to-telegram/wp-plugin-info.json" <<< "$ZIP_LISTING" \
|| fail "zip sanity: wp-plugin-info.json missing from $ZIP_PATH"
for dev in tests/ docs/ composer.json composer.lock phpunit.xml release.sh CLAUDE.md AGENTS.md .gitattributes .gitignore; do
if unzip -l "$ZIP_PATH" | grep -q "cf7-spam-to-telegram/${dev}"; then
if grep -q "cf7-spam-to-telegram/${dev}" <<< "$ZIP_LISTING"; then
fail "zip sanity: dev file must not be in zip: $dev"
fi
done
@@ -178,7 +182,7 @@ CREATE_RESPONSE="$(curl -fsSL \
-H "Content-Type: application/json" \
-d "$CREATE_PAYLOAD")"
RELEASE_ID="$(echo "$CREATE_RESPONSE" | jq -r '.id')"
RELEASE_ID="$(jq -r '.id' <<< "$CREATE_RESPONSE")"
[[ -n "$RELEASE_ID" && "$RELEASE_ID" != "null" ]] \
|| fail "Gitea create-release response missing id: $CREATE_RESPONSE"
@@ -188,14 +192,28 @@ log "Created Gitea release id=$RELEASE_ID"
log "Uploading asset $ZIP_NAME to release id=$RELEASE_ID"
UPLOAD_RESPONSE="$(curl -fsSL \
curl -fsSL \
-X POST "${GITEA_API}/repos/${REPO_OWNER}/${REPO_NAME}/releases/${RELEASE_ID}/assets?name=${ZIP_NAME}" \
-H "Authorization: token ${TOKEN}" \
-F "attachment=@${ZIP_PATH};type=application/zip")"
-F "attachment=@${ZIP_PATH};type=application/zip" \
-o /dev/null
# Gitea's asset upload response returns an internal /attachments/<uuid> URL,
# but the release detail endpoint returns the pretty /releases/download/<tag>/<name>
# URL for the same asset. Both resolve to the same bytes; the pretty URL is
# preferred for readability and WP-admin UX.
RELEASE_DETAIL="$(curl -fsSL \
"${GITEA_API}/repos/${REPO_OWNER}/${REPO_NAME}/releases/${RELEASE_ID}" \
-H "Authorization: token ${TOKEN}")"
# Use herestring instead of `echo | jq`: `echo` on macOS may interpret
# backslash-escapes in a multi-line release body, corrupting the JSON.
DOWNLOAD_URL="$(jq -r --arg name "$ZIP_NAME" \
'.assets[] | select(.name == $name) | .browser_download_url' \
<<< "$RELEASE_DETAIL" | head -n 1)"
DOWNLOAD_URL="$(echo "$UPLOAD_RESPONSE" | jq -r '.browser_download_url')"
[[ -n "$DOWNLOAD_URL" && "$DOWNLOAD_URL" != "null" ]] \
|| fail "Gitea asset upload response missing browser_download_url: $UPLOAD_RESPONSE"
|| fail "release $RELEASE_ID has no asset named $ZIP_NAME"
log "Asset uploaded: $DOWNLOAD_URL"
+14 -6
View File
@@ -54,15 +54,23 @@ final class UpdateCheckerIntegrationTest extends Cf7stgTestCase
);
}
public function test_wp_plugin_info_json_download_url_contains_expected_asset_name(): void
public function test_wp_plugin_info_json_download_url_is_gitea_asset_url(): void
{
$data = json_decode(file_get_contents(self::WP_PLUGIN_INFO_JSON), true);
$expectedAssetName = 'cf7-spam-to-telegram-' . $data['version'] . '.zip';
self::assertStringContainsString(
$expectedAssetName,
$data['download_url'],
"download_url must contain expected asset name $expectedAssetName"
$url = $data['download_url'];
self::assertNotEmpty($url, 'download_url must not be empty');
self::assertStringStartsWith(
'https://git.netranking.ru/',
$url,
'download_url must point to our Gitea host'
);
// Gitea returns one of two formats for release asset URLs:
// https://git.netranking.ru/<owner>/<repo>/releases/download/<tag>/<name>
// https://git.netranking.ru/attachments/<uuid>
// We cannot assert the asset name in the URL because the UUID format
// (used by git.netranking.ru) omits the filename entirely. Freshness
// is enforced indirectly: the plugin version must match CF7STG_VERSION
// (see test above), so a stale JSON would fail that test instead.
}
public function test_plugin_class_has_register_update_checker_method(): void
+14 -14
View File
File diff suppressed because one or more lines are too long