mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 22:27:13 +01:00
Some checks are pending
crdt-sync pre-commit / pre-commit (push) Waiting to run
crdt-sync tests / test (push) Waiting to run
dependency freshness / dependencies on newest stable (push) Waiting to run
file length / file-length (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
palette drift / palette (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
shared gate tests / gate unit tests (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
65 lines
2.1 KiB
Python
65 lines
2.1 KiB
Python
# Copyright (c) 2026 Krzysztof Rudnicki
|
|
"""Tests for ``tool/_pkce``: the verifier/challenge pair, consent URL, browser."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock
|
|
import urllib.parse
|
|
|
|
from tool import _pkce
|
|
|
|
# The worked example from RFC 7636 appendix B.
|
|
_RFC_VERIFIER = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
|
|
_RFC_CHALLENGE = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
|
|
|
|
|
|
def test_challenge_matches_the_rfc_vector() -> None:
|
|
assert _pkce.challenge_for(_RFC_VERIFIER) == _RFC_CHALLENGE
|
|
|
|
|
|
def test_make_pkce_is_random_and_self_consistent() -> None:
|
|
first, second = _pkce.make_pkce(), _pkce.make_pkce()
|
|
assert first.verifier != second.verifier
|
|
assert 43 <= len(first.verifier) <= 128
|
|
assert first.challenge == _pkce.challenge_for(first.verifier)
|
|
|
|
|
|
def test_consent_url_carries_every_pkce_field() -> None:
|
|
url = _pkce.build_consent_url(
|
|
client_id="cid",
|
|
redirect_uri="http://127.0.0.1:5555",
|
|
challenge="chal",
|
|
state="st",
|
|
login_hint="me@example.com",
|
|
)
|
|
parsed = urllib.parse.urlparse(url)
|
|
query = {k: v[0] for k, v in urllib.parse.parse_qs(parsed.query).items()}
|
|
assert parsed.netloc == "accounts.google.com"
|
|
assert query == {
|
|
"client_id": "cid",
|
|
"redirect_uri": "http://127.0.0.1:5555",
|
|
"response_type": "code",
|
|
"scope": "openid email profile",
|
|
"state": "st",
|
|
"code_challenge": "chal",
|
|
"code_challenge_method": "S256",
|
|
"login_hint": "me@example.com",
|
|
"prompt": "select_account",
|
|
}
|
|
|
|
|
|
def test_open_detached_spawns_a_new_session() -> None:
|
|
popen = MagicMock()
|
|
which = MagicMock(side_effect=lambda name: f"/usr/bin/{name}")
|
|
assert _pkce.open_detached("https://x", popen=popen, which=which) is True
|
|
args, kwargs = popen.call_args
|
|
assert args[0] == ["/usr/bin/setsid", "/usr/bin/xdg-open", "https://x"]
|
|
assert kwargs["start_new_session"] is True
|
|
|
|
|
|
def test_open_detached_reports_missing_tools() -> None:
|
|
popen = MagicMock()
|
|
which = MagicMock(return_value=None)
|
|
assert _pkce.open_detached("https://x", popen=popen, which=which) is False
|
|
popen.assert_not_called()
|