fix: verify success completion signal + cross-session verify_url restore
_on_verify_success() was missing _nickserv_complete() call, causing _go_ready() to hang at _nickserv_done.wait() when registration completed immediately (no email verification needed). get_pending_registration() was not returning verify_url from the DB, so _resume_pending_verification() never restored self._verify_url -- breaking cross-session captcha resume for OFTC-style networks. Four regression tests added. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1058,6 +1058,35 @@ class TestHandleNickserv:
|
||||
assert net._nickserv_pending == ""
|
||||
bl.mark_nickserv_verified.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_verify_success_signals_completion(self) -> None:
|
||||
"""_on_verify_success must signal _nickserv_done."""
|
||||
bl = _mock_backlog()
|
||||
net = _net(backlog=bl)
|
||||
net.nick = "verified_nick"
|
||||
net._nickserv_pending = "verify"
|
||||
net._nickserv_password = "pass"
|
||||
net._nickserv_done = asyncio.Event()
|
||||
|
||||
await net._handle_nickserv("verified_nick has been verified")
|
||||
assert net._nickserv_pending == ""
|
||||
assert net._nickserv_done.is_set()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_registration_immediate_signals_completion(self) -> None:
|
||||
"""Immediate registration (no email) must signal _nickserv_done."""
|
||||
bl = _mock_backlog()
|
||||
net = _net(backlog=bl)
|
||||
net.nick = "fastnick"
|
||||
net._nickserv_pending = "register"
|
||||
net._nickserv_password = "pass"
|
||||
net._nickserv_done = asyncio.Event()
|
||||
|
||||
await net._handle_nickserv("Nickname registered under your account")
|
||||
assert net._nickserv_pending == ""
|
||||
assert net._nickserv_done.is_set()
|
||||
bl.mark_nickserv_verified.assert_awaited_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_verify_failure(self) -> None:
|
||||
net = _net()
|
||||
@@ -1068,6 +1097,46 @@ class TestHandleNickserv:
|
||||
await net._handle_nickserv("Invalid verification code")
|
||||
assert net._nickserv_pending == ""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resume_pending_restores_verify_url(self) -> None:
|
||||
"""Cross-session resume must restore the verify_url from DB."""
|
||||
bl = _mock_backlog(
|
||||
pending=("oldnick", "pass", "e@mail.tm", "host", "https://oftc/verify/abc"),
|
||||
)
|
||||
net = _net(backlog=bl)
|
||||
net.state = State.READY
|
||||
net._running = True
|
||||
net.nick = "oldnick"
|
||||
writer = MagicMock()
|
||||
writer.is_closing.return_value = False
|
||||
writer.drain = AsyncMock()
|
||||
net._writer = writer
|
||||
|
||||
result = await net._resume_pending_verification()
|
||||
assert result is True
|
||||
assert net._verify_url == "https://oftc/verify/abc"
|
||||
assert net._nickserv_email == "e@mail.tm"
|
||||
assert net._nickserv_password == "pass"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resume_pending_no_url(self) -> None:
|
||||
"""Resume works when verify_url is empty."""
|
||||
bl = _mock_backlog(
|
||||
pending=("nick", "pass", "e@mail.tm", "host", ""),
|
||||
)
|
||||
net = _net(backlog=bl)
|
||||
net.state = State.READY
|
||||
net._running = True
|
||||
net.nick = "nick"
|
||||
writer = MagicMock()
|
||||
writer.is_closing.return_value = False
|
||||
writer.drain = AsyncMock()
|
||||
net._writer = writer
|
||||
|
||||
result = await net._resume_pending_verification()
|
||||
assert result is True
|
||||
assert net._verify_url == ""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_late_registration_confirmation(self) -> None:
|
||||
"""After timeout clears pending state, late confirmation still works."""
|
||||
|
||||
Reference in New Issue
Block a user