mirror of
https://github.com/alexgetmancom/miband-bot.git
synced 2026-07-17 19:20:13 +03:00
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
"""测试 CLI 入口与二维码登录。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
from pathlib import Path
|
|
from types import SimpleNamespace
|
|
from typing import ClassVar, Self
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
|
|
import mi_fitness.cli as cli
|
|
|
|
|
|
def _workspace_tmp_dir() -> Path:
|
|
root = Path(".test-tmp") / uuid4().hex
|
|
root.mkdir(parents=True, exist_ok=True)
|
|
return root
|
|
|
|
|
|
class _FakeAuth:
|
|
instances: ClassVar[list["_FakeAuth"]] = []
|
|
|
|
def __init__(self, *args: object):
|
|
self.args = args
|
|
self.token = SimpleNamespace(user_id="3188565001")
|
|
self.saved_path: Path | None = None
|
|
self.login_calls: list[tuple[object, ...]] = []
|
|
_FakeAuth.instances.append(self)
|
|
|
|
async def __aenter__(self) -> Self:
|
|
return self
|
|
|
|
async def __aexit__(self, exc_type, exc, tb) -> None:
|
|
return None
|
|
|
|
async def login_qr(self, qr_callback=None) -> None: # type: ignore[no-untyped-def]
|
|
self.login_calls.append(("qr",))
|
|
if qr_callback is not None:
|
|
await qr_callback("https://example.com/qr.png", "https://example.com/login")
|
|
|
|
def save_token(self, path: Path | str) -> None:
|
|
self.saved_path = Path(path)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_qr_login_saves_token(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]) -> None:
|
|
_FakeAuth.instances.clear()
|
|
tmp_dir = _workspace_tmp_dir()
|
|
monkeypatch.setattr(cli, "XiaomiAuth", _FakeAuth)
|
|
monkeypatch.setattr(cli, "TOKEN_FILE", tmp_dir / "token.json")
|
|
try:
|
|
await cli._qr_login()
|
|
auth = _FakeAuth.instances[-1]
|
|
assert auth.login_calls == [("qr",)]
|
|
assert auth.saved_path == tmp_dir / "token.json"
|
|
stdout = capsys.readouterr().out
|
|
assert "https://example.com/login" not in stdout
|
|
assert "https://example.com/qr.png" not in stdout
|
|
finally:
|
|
shutil.rmtree(tmp_dir, ignore_errors=True)
|
|
|
|
|
|
def test_main_runs_without_args(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
called = False
|
|
|
|
async def fake_qr_login() -> None:
|
|
nonlocal called
|
|
called = True
|
|
|
|
monkeypatch.setattr(cli, "_qr_login", fake_qr_login)
|
|
cli.main()
|
|
assert called
|