_finish первой же строкой вызывал EventLogService.log_event — метода с таким именем у сервиса нет, есть log(category, message, details, level). AttributeError уходил в обработчик Tk, а под pythonw консоли нет, поэтому для владельца кнопка просто не работала: окно оставалось открытым, on_complete не вызывался, аккаунт не попадал в маршрутизацию. Вызов приведён к настоящему API. Журналирование и обратный вызов обёрнуты так, чтобы сбой в них не запирал пользователя в мастере, — закрытие окна не должно зависеть от побочных действий. Воспроизведено и проверено исполнением: до правки winfo_exists=1 и on_complete не вызван, после — окно уничтожено, результат передан. Тесты: 252 passed в venv Hermes. Единственный сбой (test_oauth_lifecycle::test_f_copy_before_open_browser, TclError) и FAILED релизного гейта воспроизводятся на чистом main и к этой правке отношения не имеют. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
63 lines
2 KiB
Python
63 lines
2 KiB
Python
"""Мастер подключения обязан закрываться по кнопке «Завершить».
|
||
|
||
Дефект, ради которого написан файл: `_finish` вызывал
|
||
`EventLogService.log_event` — метода, которого у сервиса нет. Под `pythonw`
|
||
консоли нет, трейсбек Tk уходил в никуда, и для пользователя кнопка
|
||
«Завершить подключение» просто не работала: окно оставалось открытым,
|
||
аккаунт в маршрутизацию не попадал.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import pytest
|
||
|
||
pytest.importorskip("customtkinter")
|
||
|
||
import customtkinter as ctk
|
||
|
||
from antigravity_provider.router.ui.add_account_wizard import AddAccountWizard
|
||
|
||
|
||
@pytest.fixture(scope="module")
|
||
def root():
|
||
app = ctk.CTk()
|
||
app.withdraw()
|
||
yield app
|
||
try:
|
||
app.destroy()
|
||
except Exception:
|
||
pass
|
||
|
||
|
||
def _wizard(root, on_complete=None):
|
||
w = AddAccountWizard(root, on_complete=on_complete)
|
||
w.withdraw()
|
||
w.selected_provider = "antigravity"
|
||
w.target_slot = "ag-w2"
|
||
w.discovered_identity = "user@example.com"
|
||
return w
|
||
|
||
|
||
def test_finish_closes_wizard_and_reports_result(root):
|
||
seen = []
|
||
w = _wizard(root, on_complete=seen.append)
|
||
|
||
w._finish()
|
||
|
||
assert w.winfo_exists() == 0, "окно мастера осталось открытым после «Завершить»"
|
||
assert seen == [
|
||
{"provider": "antigravity", "profile_id": "ag-w2", "identity": "user@example.com"}
|
||
]
|
||
|
||
|
||
def test_finish_closes_even_if_callback_raises(root):
|
||
"""Сбой в обработчике владельца не должен запирать пользователя в мастере."""
|
||
|
||
def boom(_result):
|
||
raise RuntimeError("обновление данных упало")
|
||
|
||
w = _wizard(root, on_complete=boom)
|
||
|
||
w._finish()
|
||
|
||
assert w.winfo_exists() == 0
|