mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 20:42:26 +00:00
197 lines
5.5 KiB
Python
197 lines
5.5 KiB
Python
"""Tests for openbb_cli.codegen.credentials — credential name detection."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from openbb_cli.codegen import credentials as cr
|
|
|
|
# --- normalize_credential_key ---
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"raw,expected",
|
|
[
|
|
("api_key", "api_key"),
|
|
("API-KEY", "api_key"),
|
|
("X-API-Key", "x_api_key"),
|
|
("apikey", "apikey"),
|
|
("App-Token", "app_token"),
|
|
("Authorization", "authorization"),
|
|
("__leading__trailing__", "leading__trailing"),
|
|
],
|
|
)
|
|
def test_normalize_credential_key_canonicalizes_separators_and_case(raw, expected):
|
|
assert cr.normalize_credential_key(raw) == expected
|
|
|
|
|
|
# --- is_credential_name ---
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"name",
|
|
[
|
|
"api_key",
|
|
"api_token",
|
|
"api-token",
|
|
"apikey",
|
|
"API_KEY",
|
|
"X-API-Key",
|
|
"x-api-key",
|
|
"app_token",
|
|
"client_id",
|
|
"client_secret",
|
|
"Authorization",
|
|
"subscription_key",
|
|
"Ocp-Apim-Subscription-Key",
|
|
"bearer_token",
|
|
"session_token",
|
|
"private_key",
|
|
],
|
|
)
|
|
def test_is_credential_name_recognizes_canonical_credentials(name):
|
|
assert cr.is_credential_name(name) is True
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"name",
|
|
[
|
|
"symbol",
|
|
"limit",
|
|
"from_date",
|
|
"x_columns",
|
|
"interval",
|
|
"format",
|
|
"page_size",
|
|
],
|
|
)
|
|
def test_is_credential_name_rejects_regular_params(name):
|
|
assert cr.is_credential_name(name) is False
|
|
|
|
|
|
# --- classify_parameter ---
|
|
|
|
|
|
def test_classify_parameter_returns_query_for_query_credential():
|
|
p = {"name": "api_key", "in": "query"}
|
|
assert cr.classify_parameter(p) == "query"
|
|
|
|
|
|
def test_classify_parameter_returns_header_for_header_credential():
|
|
p = {"name": "Authorization", "in": "header"}
|
|
assert cr.classify_parameter(p) == "header"
|
|
|
|
|
|
def test_classify_parameter_defaults_to_query_when_in_unset():
|
|
"""A credential without an ``in`` location is treated as query (most common)."""
|
|
p = {"name": "api_key"}
|
|
assert cr.classify_parameter(p) == "query"
|
|
|
|
|
|
def test_classify_parameter_returns_none_for_regular_param():
|
|
p = {"name": "symbol", "in": "query"}
|
|
assert cr.classify_parameter(p) is None
|
|
|
|
|
|
def test_classify_parameter_returns_none_for_unnamed_param():
|
|
"""A malformed param entry without ``name`` is gracefully skipped."""
|
|
assert cr.classify_parameter({}) is None
|
|
assert cr.classify_parameter({"name": 42, "in": "query"}) is None # type: ignore[arg-type]
|
|
|
|
|
|
def test_classify_parameter_returns_none_for_non_dict_input():
|
|
"""Defensive: a stray non-dict in the parameters list doesn't crash."""
|
|
assert cr.classify_parameter("not-a-dict") is None # type: ignore[arg-type]
|
|
|
|
|
|
# --- credentials_from_command ---
|
|
|
|
|
|
def test_credentials_from_command_extracts_query_and_header_entries():
|
|
cmd = {
|
|
"parameters": [
|
|
{"name": "symbol", "in": "query"},
|
|
{"name": "api_key", "in": "query"},
|
|
{"name": "Authorization", "in": "header"},
|
|
]
|
|
}
|
|
out = cr.credentials_from_command(cmd)
|
|
assert out == {
|
|
"api_key": {"name": "api_key", "in": "query"},
|
|
"authorization": {"name": "Authorization", "in": "header"},
|
|
}
|
|
|
|
|
|
def test_credentials_from_command_returns_empty_when_no_creds():
|
|
assert cr.credentials_from_command({"parameters": [{"name": "limit"}]}) == {}
|
|
|
|
|
|
def test_credentials_from_command_handles_missing_parameters_key():
|
|
assert cr.credentials_from_command({}) == {}
|
|
|
|
|
|
# --- credentials_from_spec ---
|
|
|
|
|
|
def test_credentials_from_spec_aggregates_across_commands():
|
|
spec = {
|
|
"commands": {
|
|
"a": {"parameters": [{"name": "api_key", "in": "query"}]},
|
|
"b": {"parameters": [{"name": "Authorization", "in": "header"}]},
|
|
"c": {"parameters": [{"name": "symbol", "in": "query"}]},
|
|
}
|
|
}
|
|
out = cr.credentials_from_spec(spec)
|
|
assert set(out) == {"api_key", "authorization"}
|
|
assert out["api_key"]["name"] == "api_key"
|
|
assert out["authorization"]["in"] == "header"
|
|
|
|
|
|
def test_credentials_from_spec_first_occurrence_wins_on_collision():
|
|
"""If two commands declare the same canonical key with different spellings,
|
|
the first one encountered keeps its on-the-wire spelling."""
|
|
spec = {
|
|
"commands": {
|
|
"a": {"parameters": [{"name": "API-KEY", "in": "query"}]},
|
|
"b": {"parameters": [{"name": "api_key", "in": "header"}]},
|
|
}
|
|
}
|
|
out = cr.credentials_from_spec(spec)
|
|
assert out["api_key"]["name"] == "API-KEY"
|
|
assert out["api_key"]["in"] == "query"
|
|
|
|
|
|
def test_credentials_from_spec_returns_empty_when_no_commands():
|
|
assert cr.credentials_from_spec({}) == {}
|
|
|
|
|
|
# --- filter_user_params ---
|
|
|
|
|
|
def test_filter_user_params_strips_credential_entries():
|
|
params = [
|
|
{"name": "symbol", "in": "query"},
|
|
{"name": "api_key", "in": "query"},
|
|
{"name": "limit", "in": "query"},
|
|
{"name": "Authorization", "in": "header"},
|
|
]
|
|
out = cr.filter_user_params(params)
|
|
names = [p["name"] for p in out]
|
|
assert names == ["symbol", "limit"]
|
|
|
|
|
|
def test_filter_user_params_returns_empty_for_none_or_empty():
|
|
assert cr.filter_user_params(None) == [] # type: ignore[arg-type]
|
|
assert cr.filter_user_params([]) == []
|
|
|
|
|
|
def test_filter_user_params_does_not_mutate_input():
|
|
"""Defensive: the input list is unchanged after filtering."""
|
|
params = [
|
|
{"name": "api_key", "in": "query"},
|
|
{"name": "symbol", "in": "query"},
|
|
]
|
|
original = list(params)
|
|
cr.filter_user_params(params)
|
|
assert params == original
|