refactor: modularize registration runtime safely
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
import json
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from cpa_xai import oauth_device as oauth
|
||||
|
||||
|
||||
class Response:
|
||||
def __init__(self, body, status=200):
|
||||
self.body = body.encode("utf-8")
|
||||
self.status = status
|
||||
def __enter__(self):
|
||||
return self
|
||||
def __exit__(self, *args):
|
||||
return False
|
||||
def read(self):
|
||||
return self.body
|
||||
|
||||
|
||||
class Opener:
|
||||
def __init__(self, actions):
|
||||
self.actions = list(actions)
|
||||
self.calls = 0
|
||||
def open(self, request, timeout=None):
|
||||
self.calls += 1
|
||||
action = self.actions.pop(0)
|
||||
if isinstance(action, BaseException):
|
||||
raise action
|
||||
return action
|
||||
|
||||
|
||||
class OAuthDeviceTests(unittest.TestCase):
|
||||
def test_discovery_success(self):
|
||||
payload = {"device_authorization_endpoint": "https://auth.x.ai/device", "token_endpoint": "https://auth.x.ai/token"}
|
||||
opener = Opener([Response(json.dumps(payload))])
|
||||
with patch.object(oauth, "_build_opener", return_value=opener):
|
||||
self.assertEqual(oauth.discover(retries=0)["token_endpoint"], payload["token_endpoint"])
|
||||
|
||||
def test_discovery_cancelled_before_request(self):
|
||||
with self.assertRaisesRegex(oauth.OAuthDeviceError, "cancelled"):
|
||||
oauth.discover(cancel=lambda: True)
|
||||
|
||||
def test_discovery_retries_transient_error(self):
|
||||
payload = {"device_authorization_endpoint": "https://auth.x.ai/device", "token_endpoint": "https://auth.x.ai/token"}
|
||||
opener = Opener([TimeoutError("slow"), Response(json.dumps(payload))])
|
||||
with patch.object(oauth, "_build_opener", return_value=opener), patch.object(oauth, "_sleep_with_cancel"):
|
||||
oauth.discover(retries=1)
|
||||
self.assertEqual(opener.calls, 2)
|
||||
|
||||
def test_post_form_returns_non_json_body(self):
|
||||
opener = Opener([Response("not-json", status=502)])
|
||||
with patch.object(oauth, "_build_opener", return_value=opener):
|
||||
status, payload = oauth._post_form("https://auth.x.ai/token", {}, retries=0)
|
||||
self.assertEqual((status, payload), (502, "not-json"))
|
||||
|
||||
def test_slow_down_increases_wait(self):
|
||||
responses = [
|
||||
(400, {"error": "slow_down"}),
|
||||
(200, {"access_token": "a", "refresh_token": "r"}),
|
||||
]
|
||||
waits = []
|
||||
with patch.object(oauth, "_post_form", side_effect=responses), patch.object(oauth, "_sleep_with_cancel", side_effect=lambda seconds, cancel=None: waits.append(seconds)):
|
||||
result = oauth.poll_device_token("d", "https://auth.x.ai/token", interval=1, expires_in=60)
|
||||
self.assertEqual(result.refresh_token, "r")
|
||||
self.assertEqual(waits, [6])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user