Files
wehub-resource-sync 4b6817381b
Benchmark image — build + push to ECR (any adapter) / build + push (push) Waiting to run
CI / quality (ubuntu-latest) (push) Waiting to run
CI / test (tools-runtime) (push) Waiting to run
CI / test (e2e-general) (push) Waiting to run
CI / test (cli-runtime) (push) Waiting to run
CI / test (e2e-provider-and-openclaw) (push) Waiting to run
CI / test (integrations-and-misc) (push) Waiting to run
CI / coverage-report (push) Blocked by required conditions
CI / test-kubernetes (push) Waiting to run
CI / should-run-thorough (push) Waiting to run
CI / test-thorough (cloudwatch-demo) (push) Blocked by required conditions
CI / test-thorough (flink-ecs) (push) Blocked by required conditions
CI / test-thorough (upstream-lambda) (push) Blocked by required conditions
CI / test-thorough (prefect-ecs-fargate) (push) Blocked by required conditions
CodeQL / Analyze (python) (push) Waiting to run
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Blocked by required conditions
Release / publish-release (push) Blocked by required conditions
Release / publish-main-release (push) Blocked by required conditions
Release / prepare (push) Waiting to run
Release / verify (push) Blocked by required conditions
Release / build-python-dist (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Blocked by required conditions
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Blocked by required conditions
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Waiting to run
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Waiting to run
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

198 lines
5.9 KiB
Python

import httpx
import pytest
from integrations.trello import (
DEFAULT_TRELLO_BASE_URL,
TrelloConfig,
build_trello_config,
create_trello_card,
trello_config_from_env,
validate_trello_config,
validate_trello_connection,
)
_TEST_API_KEY = "test-trello-api-key"
_TEST_TOKEN = "test-trello-token"
_TEST_BOARD_ID = "board123"
_TEST_LIST_ID = "list123"
def _make_config(**overrides: object) -> TrelloConfig:
"""Build a TrelloConfig with sensible test defaults."""
defaults: dict[str, object] = {
"api_key": _TEST_API_KEY,
"token": _TEST_TOKEN,
"board_id": _TEST_BOARD_ID,
"list_id": _TEST_LIST_ID,
}
defaults.update(overrides)
return TrelloConfig(**defaults) # type: ignore[arg-type]
def test_build_trello_config_defaults() -> None:
config = build_trello_config({})
assert config.base_url == DEFAULT_TRELLO_BASE_URL
assert config.api_key == ""
assert config.token == ""
assert config.board_id == ""
assert config.list_id == ""
assert config.timeout_seconds == 15.0
def test_trello_config_from_env(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("TRELLO_API_KEY", _TEST_API_KEY)
monkeypatch.setenv("TRELLO_TOKEN", _TEST_TOKEN)
monkeypatch.setenv("TRELLO_BASE_URL", "https://api.trello.com/1")
monkeypatch.setenv("TRELLO_BOARD_ID", _TEST_BOARD_ID)
monkeypatch.setenv("TRELLO_LIST_ID", _TEST_LIST_ID)
config = trello_config_from_env()
assert config is not None
assert config.api_key == _TEST_API_KEY
assert config.token == _TEST_TOKEN
assert config.board_id == _TEST_BOARD_ID
assert config.list_id == _TEST_LIST_ID
assert config.base_url == "https://api.trello.com/1"
def test_trello_config_from_env_returns_none_without_credentials(
monkeypatch: pytest.MonkeyPatch,
) -> None:
monkeypatch.delenv("TRELLO_API_KEY", raising=False)
monkeypatch.delenv("TRELLO_TOKEN", raising=False)
config = trello_config_from_env()
assert config is None
def test_validate_trello_connection_success(monkeypatch: pytest.MonkeyPatch) -> None:
config = _make_config()
def fake_request_json(*_args: object, **_kwargs: object) -> dict[str, str]:
return {"id": "member123", "username": "test_user"}
monkeypatch.setattr("integrations.trello.client._request_json", fake_request_json)
result = validate_trello_connection(config=config)
assert result["username"] == "test_user"
def test_validate_trello_config_missing_api_key() -> None:
config = _make_config(api_key="", token=_TEST_TOKEN)
result = validate_trello_config(config)
assert result.ok is False
assert "api key" in result.detail.lower()
def test_validate_trello_config_missing_token() -> None:
config = _make_config(token="")
result = validate_trello_config(config)
assert result.ok is False
assert "token" in result.detail.lower()
def test_validate_trello_config_success(monkeypatch: pytest.MonkeyPatch) -> None:
config = _make_config()
def fake_validate_connection(*, config: TrelloConfig) -> dict[str, str]:
return {"id": "member123", "username": "test_user"}
monkeypatch.setattr(
"integrations.trello.client.validate_trello_connection",
fake_validate_connection,
)
result = validate_trello_config(config)
assert result.ok is True
assert "@test_user" in result.detail
def test_validate_trello_config_unauthorized(monkeypatch: pytest.MonkeyPatch) -> None:
config = _make_config(api_key="bad_key", token="bad_token")
request = httpx.Request("GET", "https://api.trello.com/1/members/me")
response = httpx.Response(401, request=request, text="unauthorized")
def fake_validate_connection(*, config: TrelloConfig) -> None:
raise httpx.HTTPStatusError(
"Client error '401 Unauthorized' for url 'https://api.trello.com/1/members/me'",
request=request,
response=response,
)
monkeypatch.setattr(
"integrations.trello.client.validate_trello_connection",
fake_validate_connection,
)
result = validate_trello_config(config)
assert result.ok is False
assert "401" in result.detail or "unauthorized" in result.detail.lower()
def test_create_trello_card_success(monkeypatch: pytest.MonkeyPatch) -> None:
config = _make_config()
def fake_request_json(*_args: object, **_kwargs: object) -> dict[str, str]:
return {
"id": "card123",
"name": "Critical incident",
"desc": "Root cause details",
"idList": _TEST_LIST_ID,
}
monkeypatch.setattr("integrations.trello.client._request_json", fake_request_json)
result = create_trello_card(
config=config,
name="Critical incident",
desc="Root cause details",
)
assert result["id"] == "card123"
assert result["name"] == "Critical incident"
def test_create_trello_card_uses_override_list_id(monkeypatch: pytest.MonkeyPatch) -> None:
config = _make_config(list_id="default_list")
captured_kwargs: dict[str, object] = {}
def fake_request_json(*_args: object, **kwargs: object) -> dict[str, str]:
captured_kwargs.update(kwargs)
return {"id": "card123", "idList": "override_list"}
monkeypatch.setattr("integrations.trello.client._request_json", fake_request_json)
result = create_trello_card(
config=config,
name="Incident",
desc="Details",
list_id="override_list",
)
assert result["id"] == "card123"
params: list[tuple[str, object]] = captured_kwargs["params"] # type: ignore[assignment]
assert ("idList", "override_list") in params
def test_create_trello_card_raises_without_list_id() -> None:
config = _make_config(list_id="")
with pytest.raises(ValueError, match="list_id"):
create_trello_card(
config=config,
name="Incident",
desc="Details",
)