187 lines
6.3 KiB
Python
187 lines
6.3 KiB
Python
"""
|
|
Тесты: auth.py — режимы, стенды, URL, cookie.
|
|
"""
|
|
import api.auth as auth
|
|
from api.http_client import API_ENDPOINTS, STANDS
|
|
|
|
|
|
def test_api_endpoint_map_has_all_three_stands():
|
|
assert list(API_ENDPOINTS) == ["dev", "test", "prod"]
|
|
assert len(STANDS) == 3
|
|
|
|
|
|
def test_polygon_url_construction(monkeypatch):
|
|
"""get_client в режиме polygon строит правильный URL."""
|
|
monkeypatch.setattr(auth, "get_mode", lambda: "polygon")
|
|
monkeypatch.setattr(auth, "get_polygon_stand", lambda: "test")
|
|
monkeypatch.setattr(auth, "get_token", lambda: "tok")
|
|
|
|
# Мокаем HttpClient чтобы не делать реальный запрос
|
|
clients = []
|
|
class FakeHttp:
|
|
def __init__(self, endpoint, token):
|
|
clients.append(endpoint)
|
|
monkeypatch.setattr(auth, "HttpClient", FakeHttp)
|
|
|
|
# Настроим POLYGON_ENDPOINT
|
|
from flask import Flask
|
|
app = Flask(__name__)
|
|
app.config["POLYGON_ENDPOINT"] = "https://polygon.test/api/v1/svc"
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
|
|
auth.get_client()
|
|
assert len(clients) == 1
|
|
assert clients[0] == "https://polygon.test/test/api/v1/svc"
|
|
|
|
|
|
def test_polygon_url_dev_stand(monkeypatch):
|
|
"""DEV-стенд в URL."""
|
|
monkeypatch.setattr(auth, "get_mode", lambda: "polygon")
|
|
monkeypatch.setattr(auth, "get_polygon_stand", lambda: "dev")
|
|
monkeypatch.setattr(auth, "get_token", lambda: "tok")
|
|
|
|
clients = []
|
|
class FakeHttp:
|
|
def __init__(self, endpoint, token):
|
|
clients.append(endpoint)
|
|
monkeypatch.setattr(auth, "HttpClient", FakeHttp)
|
|
|
|
from flask import Flask
|
|
app = Flask(__name__)
|
|
app.config["POLYGON_ENDPOINT"] = "https://polygon.test/api/v1/svc"
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
|
|
auth.get_client()
|
|
assert clients[0] == "https://polygon.test/dev/api/v1/svc"
|
|
|
|
|
|
def test_get_stand_polygon(monkeypatch):
|
|
"""get_stand в эмуляции возвращает polygon_{stand}."""
|
|
monkeypatch.setattr(auth, "get_mode", lambda: "polygon")
|
|
monkeypatch.setattr(auth, "get_polygon_stand", lambda: "prod")
|
|
assert auth.get_stand() == "polygon_prod"
|
|
|
|
|
|
def test_get_stand_polygon_default(monkeypatch):
|
|
"""get_stand по умолчанию test."""
|
|
monkeypatch.setattr(auth, "get_mode", lambda: "polygon")
|
|
monkeypatch.setattr(auth, "get_polygon_stand", lambda: "test")
|
|
assert auth.get_stand() == "polygon_test"
|
|
|
|
|
|
def test_get_mode_no_polygon_endpoint(monkeypatch):
|
|
"""Без POLYGON_ENDPOINT -> всегда cloud."""
|
|
from flask import Flask
|
|
app = Flask(__name__)
|
|
app.config["POLYGON_ENDPOINT"] = ""
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
# Мокаем request.cookies
|
|
monkeypatch.setattr(auth, "request", type('obj', (object,), {
|
|
"cookies": {}
|
|
})())
|
|
assert auth.get_mode() == "cloud"
|
|
|
|
|
|
def test_get_mode_default_polygon(monkeypatch):
|
|
"""POLYGON_ENDPOINT задан -> default polygon."""
|
|
from flask import Flask
|
|
app = Flask(__name__)
|
|
app.config["POLYGON_ENDPOINT"] = "https://polygon.test/api/v1/svc"
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
# request.cookies.get("mode", default_value)
|
|
monkeypatch.setattr(auth, "request", type('obj', (object,), {
|
|
"cookies": type('obj', (object,), {
|
|
"get": lambda s, d, default="polygon": d if d else default
|
|
})()
|
|
})())
|
|
assert auth.get_mode() == "polygon"
|
|
|
|
|
|
def test_get_token_polygon_mode(monkeypatch):
|
|
"""В эмуляции — только env-токен."""
|
|
monkeypatch.setattr(auth, "get_mode", lambda: "polygon")
|
|
from flask import Flask
|
|
app = Flask(__name__)
|
|
app.config["NUBES_API_TOKEN"] = "env-jwt"
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
assert auth.get_token() == "env-jwt"
|
|
|
|
|
|
def test_whitelist_mode_invalid(monkeypatch):
|
|
"""Невалидный mode -> default polygon."""
|
|
from flask import Flask
|
|
app = Flask(__name__)
|
|
app.config["POLYGON_ENDPOINT"] = "https://polygon.test/api/v1/svc"
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
monkeypatch.setattr(auth, "request", type('obj', (object,), {
|
|
"cookies": type('obj', (object,), {
|
|
"get": lambda s, d, default="polygon": "evil"
|
|
})()
|
|
})())
|
|
assert auth.get_mode() == "polygon" # fallback
|
|
|
|
|
|
def test_whitelist_stand_invalid(monkeypatch):
|
|
"""Невалидный stand -> default test."""
|
|
monkeypatch.setattr(auth, "request", type('obj', (object,), {
|
|
"cookies": type('obj', (object,), {
|
|
"get": lambda s, d, default="test": "../../etc"
|
|
})()
|
|
})())
|
|
assert auth.get_polygon_stand() == "test" # fallback
|
|
|
|
|
|
def test_cloud_detection_includes_prod_endpoint_from_source_map(monkeypatch):
|
|
from flask import Flask
|
|
|
|
prod_endpoint = API_ENDPOINTS["prod"]
|
|
app = Flask(__name__)
|
|
captured = {}
|
|
|
|
def fake_detect(token):
|
|
captured["token"] = token
|
|
return prod_endpoint
|
|
|
|
monkeypatch.setattr(auth, "detect_endpoint", fake_detect)
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
with app.test_request_context("/"):
|
|
assert auth._cached_detect("prod-token") == prod_endpoint
|
|
|
|
assert captured["token"] == "prod-token"
|
|
|
|
|
|
def test_detect_endpoint_tries_prod_endpoint(monkeypatch):
|
|
from api import http_client
|
|
|
|
prod_endpoint = API_ENDPOINTS["prod"]
|
|
endpoints = STANDS
|
|
attempted = []
|
|
|
|
class FakeHttpClient:
|
|
def __init__(self, endpoint, token):
|
|
self.endpoint = endpoint
|
|
|
|
def get(self, path, **kwargs):
|
|
attempted.append(self.endpoint)
|
|
if self.endpoint != prod_endpoint:
|
|
raise RuntimeError("token belongs to another stand")
|
|
return {"results": []}
|
|
|
|
monkeypatch.setattr(http_client, "HttpClient", FakeHttpClient)
|
|
|
|
assert http_client.detect_endpoint("prod-token", endpoints=endpoints) == prod_endpoint
|
|
assert attempted == endpoints
|
|
|
|
|
|
def test_get_stand_labels_prod_endpoint(monkeypatch):
|
|
from flask import Flask
|
|
|
|
prod_endpoint = API_ENDPOINTS["prod"]
|
|
app = Flask(__name__)
|
|
monkeypatch.setattr(auth, "get_mode", lambda: "cloud")
|
|
monkeypatch.setattr(auth, "get_token", lambda: "prod-token")
|
|
monkeypatch.setattr(auth, "_cached_detect", lambda token: prod_endpoint)
|
|
monkeypatch.setattr(auth, "current_app", app)
|
|
|
|
assert auth.get_stand() == "prod"
|