feat(bot): /start without a code on the demo stand opens a private copy of veteran Andrey
CI / ruff · pytest (pull_request) Successful in 2m45s
CI / ruff · pytest (pull_request) Successful in 2m45s
Refs #108 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -194,11 +194,28 @@ class TelegramChannel:
|
|||||||
await self._dispatch(chat_id, person.token, Event(type="start", params={"code": code}))
|
await self._dispatch(chat_id, person.token, Event(type="start", params={"code": code}))
|
||||||
return
|
return
|
||||||
token = await self.directory.token_for(chat_id)
|
token = await self.directory.token_for(chat_id)
|
||||||
|
if token is None and get_settings().demo_clock:
|
||||||
|
token = await self._demo_copy(chat_id)
|
||||||
if token is None:
|
if token is None:
|
||||||
await self._say(chat_id, texts.not_connected)
|
await self._say(chat_id, texts.not_connected)
|
||||||
return
|
return
|
||||||
await self._dispatch(chat_id, token, Event(type="start"))
|
await self._dispatch(chat_id, token, Event(type="start"))
|
||||||
|
|
||||||
|
async def _demo_copy(self, chat_id: int) -> str | None:
|
||||||
|
"""Demo stand (DEMO_CLOCK): `/start` without a code gets a private copy of veteran Andrey (synthetic),
|
||||||
|
starting from consent and the intake — the same entry as the ЕМИАС demo button of the web app."""
|
||||||
|
from app.api.patient_web import _fresh_demo_copy
|
||||||
|
|
||||||
|
try:
|
||||||
|
token = (await _fresh_demo_copy(start_in_chat=False)).token
|
||||||
|
except Exception:
|
||||||
|
log.exception("start: demo copy failed")
|
||||||
|
return None
|
||||||
|
if not await self.directory.bind(chat_id, token):
|
||||||
|
return None
|
||||||
|
log.info("start: demo copy bound tok=%s", _short(token))
|
||||||
|
return token
|
||||||
|
|
||||||
async def on_text(self, chat_id: int, text: str | None) -> None:
|
async def on_text(self, chat_id: int, text: str | None) -> None:
|
||||||
texts = load_texts()
|
texts = load_texts()
|
||||||
token = await self.directory.token_for(chat_id)
|
token = await self.directory.token_for(chat_id)
|
||||||
|
|||||||
+17
-1
@@ -22,6 +22,7 @@ from app.channels.telegram import (
|
|||||||
render_markup,
|
render_markup,
|
||||||
split_text,
|
split_text,
|
||||||
)
|
)
|
||||||
|
from app.config import get_settings
|
||||||
from app.db import identity_repo, session
|
from app.db import identity_repo, session
|
||||||
from app.db.bootstrap import init_db
|
from app.db.bootstrap import init_db
|
||||||
from app.dialog.contracts import Button, Event, Reply
|
from app.dialog.contracts import Button, Event, Reply
|
||||||
@@ -163,7 +164,10 @@ async def test_verified_token_without_identity_record(dbs: None, engine: Recordi
|
|||||||
assert sender.texts == [load_texts().code_invalid]
|
assert sender.texts == [load_texts().code_invalid]
|
||||||
|
|
||||||
|
|
||||||
async def test_unbound_chat_gets_not_connected(dbs: None, engine: RecordingEngine) -> None:
|
async def test_unbound_chat_gets_not_connected(
|
||||||
|
dbs: None, engine: RecordingEngine, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
|
monkeypatch.setattr(get_settings(), "demo_clock", False)
|
||||||
sender = FakeSender()
|
sender = FakeSender()
|
||||||
channel = TelegramChannel(sender)
|
channel = TelegramChannel(sender)
|
||||||
await channel.on_start(CHAT, None)
|
await channel.on_start(CHAT, None)
|
||||||
@@ -251,6 +255,18 @@ async def test_outbox_pushes_to_bound_chat_and_falls_back(dbs: None, engine: Rec
|
|||||||
assert [r.text for r in fallback.drain(TOKEN2)] == ["Как вы сегодня?"]
|
assert [r.text for r in fallback.drain(TOKEN2)] == ["Как вы сегодня?"]
|
||||||
|
|
||||||
|
|
||||||
|
async def test_start_without_code_on_demo_stand_binds_a_demo_copy(
|
||||||
|
dbs: None, engine: RecordingEngine, monkeypatch: pytest.MonkeyPatch
|
||||||
|
) -> None:
|
||||||
|
monkeypatch.setattr(get_settings(), "demo_clock", True)
|
||||||
|
sender = FakeSender()
|
||||||
|
channel = TelegramChannel(sender)
|
||||||
|
await channel.on_start(CHAT, None)
|
||||||
|
token = await channel.directory.token_for(CHAT)
|
||||||
|
assert token is not None and token.startswith("tok-andrey-")
|
||||||
|
assert [c[1].type for c in engine.calls] == ["start"]
|
||||||
|
|
||||||
|
|
||||||
async def test_start_is_noop_without_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
async def test_start_is_noop_without_token(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
monkeypatch.setattr(telegram, "get_settings", lambda: type("S", (), {"tg_bot_token": ""})())
|
monkeypatch.setattr(telegram, "get_settings", lambda: type("S", (), {"tg_bot_token": ""})())
|
||||||
before = integrations.outbox
|
before = integrations.outbox
|
||||||
|
|||||||
Reference in New Issue
Block a user