158 lines
4.9 KiB
Python
158 lines
4.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
|
|
def test_ensure_logged_in_dispatches_password_auto(monkeypatch):
|
|
from service.rpa_helpers import auth_flows
|
|
|
|
monkeypatch.setattr(auth_flows, "_is_already_logged_in", lambda p, a: False)
|
|
monkeypatch.setattr(auth_flows, "_poll_until", lambda *a, **k: True)
|
|
|
|
loc = MagicMock()
|
|
page = MagicMock()
|
|
page.url = "http://example.com"
|
|
page.locator.return_value.first = loc
|
|
|
|
account = {"auth_strategy": "password_auto", "login_id": "u", "url": "http://x"}
|
|
r = auth_flows.ensure_logged_in(page, account, credentials={"plaintext": "pw"})
|
|
assert r.ok is True
|
|
page.goto.assert_called()
|
|
assert loc.type.call_count >= 2
|
|
loc.click.assert_called()
|
|
|
|
|
|
def test_ensure_logged_in_dispatches_qr_code_manual(monkeypatch):
|
|
from service.rpa_helpers import auth_flows
|
|
|
|
monkeypatch.setattr(auth_flows, "_is_already_logged_in", lambda p, a: True)
|
|
|
|
page = MagicMock()
|
|
account = {"auth_strategy": "qr_code_manual", "url": "http://x"}
|
|
r = auth_flows.ensure_logged_in(page, account)
|
|
assert r.ok is True
|
|
|
|
|
|
def test_ensure_logged_in_client_certificate_raises():
|
|
from service.rpa_helpers.auth_flows import AuthStrategyError, ensure_logged_in
|
|
|
|
page = MagicMock()
|
|
account = {"auth_strategy": "client_certificate"}
|
|
with pytest.raises(AuthStrategyError) as ei:
|
|
ensure_logged_in(page, account)
|
|
assert ei.value.code == "ERR_AUTH_STRATEGY_NOT_AUTOMATABLE"
|
|
|
|
|
|
def test_ensure_logged_in_api_token_no_op():
|
|
from service.rpa_helpers.auth_flows import ensure_logged_in
|
|
|
|
page = MagicMock()
|
|
account = {"auth_strategy": "api_token"}
|
|
r = ensure_logged_in(page, account)
|
|
assert r.ok is True
|
|
page.goto.assert_not_called()
|
|
|
|
|
|
def test_ensure_logged_in_missing_credentials():
|
|
from service.rpa_helpers.auth_flows import AuthStrategyError, ensure_logged_in
|
|
|
|
page = MagicMock()
|
|
account = {"auth_strategy": "password_auto", "login_id": "u"}
|
|
with pytest.raises(AuthStrategyError) as ei:
|
|
ensure_logged_in(page, account, credentials=None)
|
|
assert ei.value.code == "ERR_CREDENTIAL_MISSING"
|
|
|
|
|
|
def test_ensure_logged_in_unknown_strategy():
|
|
from service.rpa_helpers.auth_flows import AuthStrategyError, ensure_logged_in
|
|
|
|
page = MagicMock()
|
|
account = {"auth_strategy": "bogus"}
|
|
with pytest.raises(AuthStrategyError) as ei:
|
|
ensure_logged_in(page, account)
|
|
assert ei.value.code == "ERR_AUTH_STRATEGY_NOT_SUPPORTED"
|
|
|
|
|
|
def test_ensure_logged_in_no_strategy():
|
|
from service.rpa_helpers.auth_flows import AuthStrategyError, ensure_logged_in
|
|
|
|
page = MagicMock()
|
|
account = {"auth_strategy": ""}
|
|
with pytest.raises(AuthStrategyError) as ei:
|
|
ensure_logged_in(page, account)
|
|
assert ei.value.code == "ERR_AUTH_STRATEGY_NOT_SUPPORTED"
|
|
|
|
|
|
def test_device_bound_fingerprint_mismatch(monkeypatch):
|
|
from service.rpa_helpers.auth_flows import AuthStrategyError, ensure_logged_in
|
|
|
|
monkeypatch.setattr(
|
|
"service.rpa_helpers.auth_flows._current_machine_fingerprint",
|
|
lambda: "right_fp",
|
|
)
|
|
page = MagicMock()
|
|
account = {
|
|
"auth_strategy": "device_bound",
|
|
"device_fingerprint": "wrong_fp",
|
|
"login_id": "u",
|
|
"url": "http://x",
|
|
}
|
|
with pytest.raises(AuthStrategyError) as ei:
|
|
ensure_logged_in(page, account, credentials={"plaintext": "pw"})
|
|
assert ei.value.code == "ERR_DEVICE_FINGERPRINT_MISMATCH"
|
|
|
|
|
|
def test_is_already_logged_in_default_false():
|
|
from service.rpa_helpers.auth_flows import _is_already_logged_in
|
|
|
|
p = MagicMock()
|
|
p.url = "about:blank"
|
|
assert _is_already_logged_in(p, {}) is False
|
|
|
|
p.url = "https://www.douyin.com"
|
|
assert _is_already_logged_in(p, {}) is False
|
|
|
|
p.url = "https://www.douyin.com/user/abc"
|
|
assert _is_already_logged_in(
|
|
p,
|
|
{"extra_json": {"logged_in_url_pattern": r"/user/"}},
|
|
) is True
|
|
|
|
loc_first = MagicMock()
|
|
loc_first.is_visible.return_value = True
|
|
loc = MagicMock()
|
|
loc.first = loc_first
|
|
p2 = MagicMock()
|
|
p2.url = "https://example.com/home"
|
|
p2.locator.return_value = loc
|
|
assert _is_already_logged_in(
|
|
p2,
|
|
{"extra_json": {"logged_in_selector": "#avatar"}},
|
|
) is True
|
|
p2.locator.assert_called_with("#avatar")
|
|
|
|
|
|
def test_qr_code_manual_default_no_hooks():
|
|
from service.rpa_helpers.auth_flows import ensure_logged_in
|
|
|
|
qr_first = MagicMock()
|
|
qr_first.wait_for.side_effect = TimeoutError("mock qr timeout")
|
|
qr_loc = MagicMock()
|
|
qr_loc.first = qr_first
|
|
page = MagicMock()
|
|
page.url = "about:blank"
|
|
page.locator.return_value = qr_loc
|
|
|
|
account = {"auth_strategy": "qr_code_manual", "url": "http://login.example"}
|
|
r = ensure_logged_in(page, account)
|
|
page.goto.assert_called_once_with(
|
|
"http://login.example",
|
|
wait_until="domcontentloaded",
|
|
timeout=60000,
|
|
)
|
|
qr_first.wait_for.assert_called_once()
|
|
assert r.ok is False
|
|
assert r.message == "qr code not found"
|
|
|