diff --git a/CHANGELOG.md b/CHANGELOG.md index ac3ddc7..6f95c08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -364,6 +364,23 @@ Hysteria-интеграции с официальной документацие тестом с настоящими сокетами, а гейт приёмки запрещает возврат `IsLoopback()` и требует негативного случая в тестах. +### Исправлено — устаревшие утверждения приёмки + +- **Гейт «frontend ACME registry matches current upstream» описывал снятую + архитектуру.** Он требовал, чтобы страница Hysteria содержала жёсткий список + ACME DNS-провайдеров (`cloudflare` … `vultr`) и не содержала удалённого + upstream `namedotcom`. Это имело смысл, пока панель ПРЕДЛАГАЛА выбор + провайдера: список в UI был вторым экземпляром upstream-реестра и мог от него + отстать. После перевода страницы в read-only диагностику реестра нет и быть не + должно — имя провайдера читается из фактического конфига и показывается как + есть, поэтому новый upstream-провайдер отображается без правок панели. + Возврат списка ради прохождения grep'а создал бы фиктивный реестр, + существующий только для гейта, поэтому исправлен гейт: он проверяет + действующий контракт (провайдер приходит строкой и рисуется как значение, + параметры DNS — только именами, селектора на странице нет). То же утверждение + поправлено в матрице приёмки, а контрактный тест панели теперь требует + ОТСУТСТВИЯ всех восьми имён провайдеров в исходнике страницы. + ### Исправлено — зависимости frontend - **`browserslist@4.21.11` содержал high-advisory** (уязвимы `<= 4.28.6`) и diff --git a/docs/testing/11-2-builder-layer.md b/docs/testing/11-2-builder-layer.md index 44c97a1..5e6d481 100644 --- a/docs/testing/11-2-builder-layer.md +++ b/docs/testing/11-2-builder-layer.md @@ -726,6 +726,15 @@ credentials получает новую идентичность сессий». адрес auth-URL, имена параметров ACME DNS); - отсутствующий файл конфига — отказ, а не пустой профиль. +`tools/test/frontend-contract.test.ts` закрепляет ту же границу со стороны +панели: имя ACME DNS-провайдера показывается как фактическое значение профиля +(`text(profile.acme.dnsProvider)`), тип поля — обычная строка, а собственного +списка провайдеров в панели нет. Проверка перечисляет их поимённо +(`cloudflare`, `duckdns`, …, `namedotcom`) и требует, чтобы **ни один** не +встречался в исходнике страницы: реестр в UI был бы вторым экземпляром +upstream-списка, который умеет от него отстать — ровно так `namedotcom` +пришлось выпиливать вручную после его удаления в Hysteria 2.11.0. + `apps/service/hysteria2_export_test.go` дополнен якорями YAML: секрет за `&anchor`/`*alias` вырезается и по ссылке, и в самом объявлении; URL с учётными данными за якорем — тоже; ссылка на составной узел редактируется целиком; diff --git a/docs/testing/11-5-negative-and-matrix.md b/docs/testing/11-5-negative-and-matrix.md index db1ddd7..1cfb547 100644 --- a/docs/testing/11-5-negative-and-matrix.md +++ b/docs/testing/11-5-negative-and-matrix.md @@ -119,7 +119,7 @@ 28. экспорт не уничтожает современные и неизвестные upstream-поля 29. экспорт не содержит секретов 30. frontend отображает Gecko -31. `namedotcom` удалён, актуальные ACME-провайдеры отражены +31. панель показывает фактическое имя ACME DNS-провайдера из конфига и **не содержит** собственного списка провайдеров: страница Hysteria — read-only диагностика, выбирать провайдера она не предлагает, поэтому новый upstream-провайдер отображается без правок панели 32. документация нигде не утверждает, что Salamander — фиксированный инвариант 33. документация не фиксирует конкретный номер версии как «текущую версию», а объясняет latest-stable build policy 34. форма создания пира содержит примеры значений и пояснения для полей «Пир», «Комментарий» и «Секрет» diff --git a/tools/build/lib/acceptance.sh b/tools/build/lib/acceptance.sh index 0ac7e68..4a6d870 100644 --- a/tools/build/lib/acceptance.sh +++ b/tools/build/lib/acceptance.sh @@ -205,15 +205,41 @@ run_fix20_acceptance_subset() { grep -q 'GetRawHysteria2Config' apps/service/hysteria2_export.go \ || fail "acceptance: export must read the raw YAML instead of the typed model" - log_step "Acceptance: frontend ACME registry matches current upstream" - # Ищем именно предлагаемое значение, а не упоминание в комментарии. - ! grep -q '"namedotcom"' apps/frontend/src/views/hysteria/list/index.vue \ - || fail "acceptance: namedotcom was removed upstream in Hysteria 2.11.0 and must not be offered" - local provider - for provider in cloudflare duckdns gandi godaddy namecheap njalla porkbun vultr; do - grep -q "\"${provider}\"" apps/frontend/src/views/hysteria/list/index.vue \ - || fail "acceptance: ACME DNS provider ${provider} is missing from the UI registry" - done + log_step "Acceptance: frontend ACME diagnostics preserve upstream provider names" + # Этот гейт проверял НЕ ТО, и его предмет исчез вместе с прежней страницей. + # + # Раньше он требовал, чтобы `apps/frontend/src/views/hysteria/list/index.vue` + # содержал жёстко заданный список ACME DNS-провайдеров + # + # cloudflare duckdns gandi godaddy namecheap njalla porkbun vultr + # + # и не содержал `namedotcom`, удалённый upstream в Hysteria 2.11.0. Это имело + # смысл ровно до тех пор, пока панель ПРЕДЛАГАЛА оператору выбор провайдера: + # список в UI был вторым экземпляром upstream-реестра и мог от него отстать. + # + # Панель больше ничего не предлагает: конфигом владеет оркестратор, маршрутов + # записи в API нет, а страница Hysteria стала read-only диагностикой. Имя + # провайдера читается из фактического конфига и показывается как есть, поэтому + # реестра в UI нет и быть не должно — новый upstream-провайдер отображается + # без единой правки панели. + # + # Возврат старого списка ради прохождения этого grep'а создал бы фиктивный + # реестр, существующий только для гейта. Поэтому проверяется действующий + # контракт: провайдер приходит из профиля строкой и рисуется как значение. + local hysteria_page="apps/frontend/src/views/hysteria/list/index.vue" + local hysteria_types="apps/frontend/src/api/config/types.ts" + + code_has "$hysteria_page" -F -- 'text(profile.acme.dnsProvider)' \ + || fail "acceptance: the panel must render the ACME DNS provider reported by the backend" + code_has "$hysteria_types" -E -- 'dnsProvider:[[:space:]]*string[[:space:]]*\|[[:space:]]*null' \ + || fail "acceptance: the ACME profile must carry the provider name as a generic string" + # Значения параметров DNS-провайдера — ключ от DNS-зоны, и read-only экрану + # они не нужны: показываются только имена. + code_has "$hysteria_types" -F -- 'dnsConfigKeys: string[]' \ + || fail "acceptance: the ACME DNS parameters must be exposed as key names only" + # Селектор провайдера означал бы возврат к «панель владеет конфигом». + ! code_has "$hysteria_page" -F -- ' { } }); + // Имя ACME DNS-провайдера показывается как ФАКТИЧЕСКОЕ значение профиля. + // + // Прежняя страница несла жёсткий список провайдеров, то есть второй экземпляр + // upstream-реестра, который мог от него отстать: `namedotcom` пришлось + // выпиливать вручную после удаления в Hysteria 2.11.0. Панель больше ничего + // не предлагает — конфигом владеет оркестратор, — поэтому реестра в UI нет и + // быть не должно: новый upstream-провайдер отображается без правок панели. + test("ACME DNS provider показывается как фактическое значение профиля", () => { + const source = vueCodeOf(configPage()); + const types = codeOf(configTypes()); + + expect(source).toContain("profile.acme.dnsProvider"); + expect(source).toContain("text(profile.acme.dnsProvider)"); + expect(types).toContain("dnsProvider: string | null"); + + // Реестр провайдеров в панели не возвращается ни под каким видом. + for (const provider of [ + "cloudflare", + "duckdns", + "gandi", + "godaddy", + "namecheap", + "njalla", + "porkbun", + "vultr", + "namedotcom", + ]) { + expect(source).not.toContain(`"${provider}"`); + } + + // Значения параметров DNS — ключ от DNS-зоны: read-only экран получает + // только их имена. + expect(types).toContain("dnsConfigKeys: string[]"); + expect(types).not.toMatch(/dnsConfig:\s*(Record|\{)/); + }); + // Компоненты генерического редактора удалены вместе со страницей: пока они // существуют, «универсальный редактор Hysteria» отрастает заново. test("компоненты генерического редактора удалены", () => {