Initial kilocode: Kilo.ai token provider with Selenium Firefox + Google OAuth
This commit is contained in:
commit
061eefdb24
17 changed files with 1629 additions and 0 deletions
12
tests/conftest.py
Normal file
12
tests/conftest.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _add_src_to_path() -> None:
|
||||
root = Path(__file__).resolve().parents[1]
|
||||
src = root / "src"
|
||||
if str(src) not in sys.path:
|
||||
sys.path.insert(0, str(src))
|
||||
|
||||
|
||||
_add_src_to_path()
|
||||
11
tests/test_proxy.py
Normal file
11
tests/test_proxy.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
from proxy import get_proxy_url
|
||||
|
||||
|
||||
def test_returns_none_when_empty(monkeypatch):
|
||||
monkeypatch.setattr("proxy.PROXY_URL", "")
|
||||
assert get_proxy_url() is None
|
||||
|
||||
|
||||
def test_returns_value(monkeypatch):
|
||||
monkeypatch.setattr("proxy.PROXY_URL", "http://localhost:8080")
|
||||
assert get_proxy_url() == "http://localhost:8080"
|
||||
47
tests/test_registration.py
Normal file
47
tests/test_registration.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import json
|
||||
|
||||
from registration import load_google_accounts, _is_on_kilo
|
||||
import registration as reg
|
||||
|
||||
|
||||
def test_load_google_accounts(tmp_path, monkeypatch):
|
||||
mail_file = tmp_path / "mail.json"
|
||||
accounts = [
|
||||
{"email": "a@example.com", "password": "pass1"},
|
||||
{"email": "b@example.com", "password": "pass2"},
|
||||
]
|
||||
mail_file.write_text(json.dumps(accounts))
|
||||
monkeypatch.setattr(reg, "MAIL_JSON", mail_file)
|
||||
|
||||
result = load_google_accounts()
|
||||
assert len(result) == 2
|
||||
assert result[0]["email"] == "a@example.com"
|
||||
|
||||
|
||||
def test_load_missing_file(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(reg, "MAIL_JSON", tmp_path / "nope.json")
|
||||
assert load_google_accounts() == []
|
||||
|
||||
|
||||
def test_load_invalid_json(tmp_path, monkeypatch):
|
||||
f = tmp_path / "mail.json"
|
||||
f.write_text("not json")
|
||||
monkeypatch.setattr(reg, "MAIL_JSON", f)
|
||||
assert load_google_accounts() == []
|
||||
|
||||
|
||||
def test_is_on_kilo():
|
||||
assert _is_on_kilo("https://app.kilo.ai/profile") is True
|
||||
assert _is_on_kilo("https://kilo.ai/") is True
|
||||
assert (
|
||||
_is_on_kilo("https://accounts.google.com/?redirect=https://app.kilo.ai")
|
||||
is False
|
||||
)
|
||||
assert _is_on_kilo("https://example.com/kilo.ai") is False
|
||||
|
||||
|
||||
def test_load_not_array(tmp_path, monkeypatch):
|
||||
f = tmp_path / "mail.json"
|
||||
f.write_text('{"email": "a@b.com"}')
|
||||
monkeypatch.setattr(reg, "MAIL_JSON", f)
|
||||
assert load_google_accounts() == []
|
||||
72
tests/test_tokens.py
Normal file
72
tests/test_tokens.py
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import json
|
||||
|
||||
from tokens import (
|
||||
ProviderTokens,
|
||||
load_state,
|
||||
save_state,
|
||||
save_tokens,
|
||||
promote_next_tokens,
|
||||
clear_next_tokens,
|
||||
)
|
||||
import tokens as t
|
||||
|
||||
|
||||
def test_save_and_load_state(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(t, "TOKENS_FILE", tmp_path / "tokens.json")
|
||||
|
||||
active = ProviderTokens("key1", None, 0)
|
||||
nxt = ProviderTokens("key2", None, 0)
|
||||
save_state(active, nxt)
|
||||
|
||||
a, n = load_state()
|
||||
assert a is not None and a.access_token == "key1"
|
||||
assert n is not None and n.access_token == "key2"
|
||||
|
||||
|
||||
def test_promote_next_tokens(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(t, "TOKENS_FILE", tmp_path / "tokens.json")
|
||||
|
||||
save_state(ProviderTokens("key1", None, 0), ProviderTokens("key2", None, 0))
|
||||
assert promote_next_tokens() is True
|
||||
|
||||
a, n = load_state()
|
||||
assert a is not None and a.access_token == "key2"
|
||||
assert n is None
|
||||
|
||||
|
||||
def test_clear_next_tokens(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(t, "TOKENS_FILE", tmp_path / "tokens.json")
|
||||
|
||||
save_state(ProviderTokens("key1", None, 0), ProviderTokens("key2", None, 0))
|
||||
clear_next_tokens()
|
||||
|
||||
a, n = load_state()
|
||||
assert a is not None and a.access_token == "key1"
|
||||
assert n is None
|
||||
|
||||
|
||||
def test_save_tokens_preserves_next(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(t, "TOKENS_FILE", tmp_path / "tokens.json")
|
||||
|
||||
save_state(ProviderTokens("key1", None, 0), ProviderTokens("key2", None, 0))
|
||||
save_tokens(ProviderTokens("key3", None, 0))
|
||||
|
||||
a, n = load_state()
|
||||
assert a is not None and a.access_token == "key3"
|
||||
assert n is not None and n.access_token == "key2"
|
||||
|
||||
|
||||
def test_load_missing_file(tmp_path, monkeypatch):
|
||||
monkeypatch.setattr(t, "TOKENS_FILE", tmp_path / "missing.json")
|
||||
a, n = load_state()
|
||||
assert a is None and n is None
|
||||
|
||||
|
||||
def test_atomic_write(tmp_path, monkeypatch):
|
||||
f = tmp_path / "tokens.json"
|
||||
monkeypatch.setattr(t, "TOKENS_FILE", f)
|
||||
|
||||
save_state(ProviderTokens("x", None, 0), None)
|
||||
with open(f) as fp:
|
||||
data = json.load(fp)
|
||||
assert data["active"]["access_token"] == "x"
|
||||
Loading…
Add table
Add a link
Reference in a new issue