Files
gptplus_machine/tests/test_register_live_sentinel.py

130 lines
6.2 KiB
Python

import unittest
from types import SimpleNamespace
from unittest.mock import Mock, patch
class FakeResponse:
def __init__(self, *, status_code=200, text="", json_data=None, headers=None):
self.status_code = status_code
self.text = text
self._json_data = json_data
self.headers = headers or {"content-type": "application/json"}
def json(self):
return self._json_data
class RegisterLiveSentinelTests(unittest.TestCase):
def test_register_authorize_continue_and_so_token_are_used(self):
from src.chatgpt_register_http_reverse import ChatGPTRegisterHTTPReverse
flow_history: list[str] = []
def build_token(flow: str) -> str:
flow_history.append(flow)
return f"{flow}-token"
def build_session_observer_token(flow: str) -> str:
flow_history.append("session_observer")
return "session-observer-token"
fake_http = SimpleNamespace(
request=Mock(return_value=FakeResponse(json_data={"accessToken": "at", "user": {"id": "uid"}})),
session=SimpleNamespace(cookies=SimpleNamespace(jar=[])),
)
fake_mail = SimpleNamespace(
create_mailbox=Mock(return_value={"address": "user@example.com", "id": "box-1", "password": ""}),
wait_for_otp=Mock(return_value="123456"),
)
solver = SimpleNamespace(
build_token=Mock(side_effect=build_token),
build_session_observer_token=Mock(side_effect=build_session_observer_token),
)
register = ChatGPTRegisterHTTPReverse(fake_http, fake_mail, sentinel_solver=solver)
order: list[str] = []
create_call_args: dict[str, str | None] = {}
def fake_authorize_continue(*args, **kwargs):
order.append("authorize_continue")
return "https://auth.openai.com/create-account/password"
def fake_attempt_register(*args, **kwargs):
order.append("attempt_register")
return FakeResponse(status_code=200), {"continue_url": "continue-1"}
def fake_attempt_create_account(*args, sentinel=None, sentinel_so=None, **kwargs):
order.append("attempt_create")
create_call_args["sentinel"] = sentinel
create_call_args["sentinel_so"] = sentinel_so
return FakeResponse(status_code=200), {"continue_url": "continue-3"}
with patch.object(register, "_bootstrap_chatgpt", return_value="csrf"), \
patch.object(register, "_signin_auth0", return_value="auth-url"), \
patch.object(register, "_follow_auth_redirects", return_value="https://auth.openai.com/create-account/password"), \
patch.object(register, "_accounts_api_base", return_value="https://auth.openai.com/api/accounts"), \
patch.object(register, "_register_endpoint", return_value="https://auth.openai.com/api/accounts/user/register"), \
patch.object(register, "_authorize_continue", side_effect=fake_authorize_continue, create=True) as authorize_continue, \
patch.object(register, "_open_continue_url", side_effect=["email-url", "about-you-url"]), \
patch.object(register, "_validate_otp", return_value="continue-2"), \
patch.object(register, "_finalize_auth_callback"), \
patch.object(register, "_attempt_register", side_effect=fake_attempt_register) as attempt_register, \
patch.object(register, "_attempt_create_account", side_effect=fake_attempt_create_account) as attempt_create:
result = register.register("Passw0rd!", "Jane Doe")
self.assertEqual(result["email"], "user@example.com")
self.assertEqual(
flow_history,
[
"authorize_continue",
"username_password_create",
"oauth_create_account",
"session_observer",
],
)
self.assertTrue(authorize_continue.called)
self.assertEqual(authorize_continue.call_args.args[1], "https://auth.openai.com/log-in-or-create-account?usernameKind=email")
self.assertLess(order.index("authorize_continue"), order.index("attempt_register"))
self.assertEqual(attempt_register.call_args.args[1], "https://auth.openai.com/create-account/password")
self.assertEqual(attempt_register.call_args.kwargs["sentinel"], "username_password_create-token")
self.assertEqual(create_call_args["sentinel"], "oauth_create_account-token")
self.assertEqual(create_call_args["sentinel_so"], "session-observer-token")
solver.build_session_observer_token.assert_called_once_with("oauth_create_account")
def test_authorize_continue_posts_screen_hint_and_json_headers(self):
from src.chatgpt_register_http_reverse import ChatGPTRegisterHTTPReverse
captured = {}
def fake_request(method, url, **kwargs):
captured['method'] = method
captured['url'] = url
captured['kwargs'] = kwargs
return FakeResponse(status_code=200, json_data={"continue_url": "https://auth.openai.com/create-account/password"})
fake_http = SimpleNamespace(
request=fake_request,
session=SimpleNamespace(cookies=SimpleNamespace(jar=[])),
)
fake_mail = SimpleNamespace()
register = ChatGPTRegisterHTTPReverse(fake_http, fake_mail, sentinel_solver=SimpleNamespace())
with patch.object(register, '_open_continue_url', return_value='https://auth.openai.com/create-account/password'):
result = register._authorize_continue(
'https://auth.openai.com/api/accounts',
'https://auth.openai.com/log-in-or-create-account?usernameKind=email',
'user@example.com',
sentinel='authorize-token',
)
self.assertEqual(result, 'https://auth.openai.com/create-account/password')
self.assertEqual(captured['method'], 'POST')
self.assertEqual(captured['kwargs']['json']['screen_hint'], 'login_or_signup')
self.assertEqual(captured['kwargs']['headers']['Accept'], 'application/json')
self.assertEqual(captured['kwargs']['headers']['openai-sentinel-token'], 'authorize-token')
if __name__ == "__main__":
unittest.main()