"""Tests for the Trello plugin — card management feature.""" from __future__ import annotations import json import os from typing import Any import pytest pytestmark = pytest.mark.usefixtures("clear_env") @pytest.fixture(autouse=True) def clear_env(monkeypatch: pytest.MonkeyPatch) -> Any: monkeypatch.delenv("TRELLO_API_KEY", raising=False) monkeypatch.delenv("TRELLO_TOKEN", raising=False) # --------------------------------------------------------------------------- # TrelloClient — create_card # --------------------------------------------------------------------------- class TestCreateCard: def test_success(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.post("https://api.trello.com/1/cards", json={"id": "c1", "name": "My Card", "url": "https://trello.com/c/c1", "shortUrl": "https://trello.com/c/abc", "idList": "l1"}) client = TrelloClient(api_key="k", token="t") result = client.create_card(name="My Card", list_id="l1") assert result["success"] assert result["card"]["name"] == "My Card" def test_with_description_and_due(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.post("https://api.trello.com/1/cards", json={"id": "c1", "name": "Card", "url": "", "shortUrl": "", "idList": "l1"}) client = TrelloClient(api_key="k", token="t") result = client.create_card(name="Card", list_id="l1", desc="Desc", due="2026-06-01T00:00:00Z") assert result["success"] def test_missing_credentials(self) -> None: from trello_plugin.client import TrelloClient client = TrelloClient(api_key="", token="") result = client.create_card(name="Card", list_id="l1") assert not result["success"] assert "TRELLO_API_KEY" in result["message"] # --------------------------------------------------------------------------- # TrelloClient — card_details # --------------------------------------------------------------------------- class TestCardDetails: def test_success(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.get( "https://api.trello.com/1/cards/c1", json={ "id": "c1", "name": "My Card", "desc": "Description", "due": None, "dueComplete": False, "url": "https://trello.com/c/c1", "shortUrl": "https://trello.com/c/abc", "idList": "l1", "closed": False, "list": {"id": "l1", "name": "To Do"}, "members": [{"id": "m1", "username": "user1", "fullName": "User One"}], "checklists": [{"id": "cl1", "name": "Checklist", "checkItems": [{"id": "ci1", "name": "Item", "state": "incomplete"}]}], "actions": [{"id": "a1", "type": "commentCard", "data": {"text": "Nice card"}, "memberCreator": {"username": "user1"}, "date": "2026-05-01T00:00:00Z"}], }, ) client = TrelloClient(api_key="k", token="t") result = client.card_details(card_id="c1") assert result["success"] assert result["card"]["name"] == "My Card" assert len(result["card"]["members"]) == 1 assert len(result["card"]["checklists"]) == 1 assert len(result["card"]["comments"]) == 1 # --------------------------------------------------------------------------- # TrelloClient — update_card # --------------------------------------------------------------------------- class TestUpdateCard: def test_update_name(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.put("https://api.trello.com/1/cards/c1", json={"id": "c1", "name": "Updated", "desc": "", "due": None}) client = TrelloClient(api_key="k", token="t") result = client.update_card(card_id="c1", name="Updated") assert result["success"] assert result["card"]["name"] == "Updated" def test_no_changes(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient client = TrelloClient(api_key="k", token="t") result = client.update_card(card_id="c1") assert result["success"] assert "No changes" in result["message"] # --------------------------------------------------------------------------- # TrelloClient — move_card, archive_card # --------------------------------------------------------------------------- class TestMoveCard: def test_success(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.put("https://api.trello.com/1/cards/c1", json={"id": "c1", "name": "Card", "idList": "l2"}) client = TrelloClient(api_key="k", token="t") result = client.move_card(card_id="c1", list_id="l2") assert result["success"] class TestArchiveCard: def test_success(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.put("https://api.trello.com/1/cards/c1", json={"id": "c1", "name": "Card", "closed": True}) client = TrelloClient(api_key="k", token="t") result = client.archive_card(card_id="c1") assert result["success"] # --------------------------------------------------------------------------- # TrelloClient — member operations # --------------------------------------------------------------------------- class TestMemberOps: def test_assign_member(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.post("https://api.trello.com/1/cards/c1/idMembers", json={"id": "c1"}, status_code=200) client = TrelloClient(api_key="k", token="t") result = client.assign_member(card_id="c1", member_id="m1") assert result["success"] def test_remove_member(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.delete("https://api.trello.com/1/cards/c1/idMembers/m1", status_code=200, json={}) client = TrelloClient(api_key="k", token="t") result = client.remove_member(card_id="c1", member_id="m1") assert result["success"] # --------------------------------------------------------------------------- # TrelloClient — comments # --------------------------------------------------------------------------- class TestComments: def test_add_comment(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.post("https://api.trello.com/1/cards/c1/actions/comments", json={"id": "a1", "data": {"text": "Great!"}}) client = TrelloClient(api_key="k", token="t") result = client.add_comment(card_id="c1", text="Great!") assert result["success"] assert result["comment"]["id"] == "a1" def test_delete_comment(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.delete("https://api.trello.com/1/cards/c1/actions/a1/comments", status_code=200, json={}) client = TrelloClient(api_key="k", token="t") result = client.delete_comment(card_id="c1", comment_id="a1") assert result["success"] # --------------------------------------------------------------------------- # TrelloClient — checklists # --------------------------------------------------------------------------- class TestChecklistItems: def test_add_item_with_checklist_id(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.post("https://api.trello.com/1/cards/c1/checklistItems", json={"id": "ci1", "name": "Task", "state": "incomplete", "idChecklist": "cl1"}) client = TrelloClient(api_key="k", token="t") result = client.add_checklist_item(card_id="c1", name="Task", checklist_id="cl1") assert result["success"] assert result["item"]["name"] == "Task" def test_add_item_auto_discover(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient # card_details call for auto-discover requests_mock.get( "https://api.trello.com/1/cards/c1", json={ "id": "c1", "name": "Card", "desc": "", "due": None, "dueComplete": False, "url": "", "shortUrl": "", "idList": "l1", "closed": False, "list": {"id": "l1", "name": "List"}, "members": [], "checklists": [{"id": "cl1", "name": "Checklist", "checkItems": []}], "actions": [], }, ) requests_mock.post("https://api.trello.com/1/cards/c1/checklistItems", json={"id": "ci1", "name": "Auto", "state": "incomplete", "idChecklist": "cl1"}) client = TrelloClient(api_key="k", token="t") result = client.add_checklist_item(card_id="c1", name="Auto") assert result["success"] def test_toggle_complete(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.put("https://api.trello.com/1/cards/c1/checklistItem/ci1", json={"id": "ci1", "name": "Task", "state": "complete"}) client = TrelloClient(api_key="k", token="t") result = client.toggle_checklist_item(card_id="c1", item_id="ci1", checked=True) assert result["success"] assert result["item"]["state"] == "complete" def test_toggle_incomplete(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.put("https://api.trello.com/1/cards/c1/checklistItem/ci1", json={"id": "ci1", "name": "Task", "state": "incomplete"}) client = TrelloClient(api_key="k", token="t") result = client.toggle_checklist_item(card_id="c1", item_id="ci1", checked=False) assert result["success"] assert result["item"]["state"] == "incomplete" def test_delete_item(self, requests_mock: Any) -> None: from trello_plugin.client import TrelloClient requests_mock.delete("https://api.trello.com/1/cards/c1/checklistItems/ci1", status_code=200, json={}) client = TrelloClient(api_key="k", token="t") result = client.delete_checklist_item(card_id="c1", item_id="ci1") assert result["success"] # --------------------------------------------------------------------------- # Tool functions # --------------------------------------------------------------------------- class TestCardToolFunctions: def test_trello_create_card_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_create_card os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.post("https://api.trello.com/1/cards", json={"id": "c1", "name": "Card", "url": "", "shortUrl": "", "idList": "l1"}) result = json.loads(trello_create_card(name="Card", list_id="l1")) assert result["success"] def test_trello_card_details_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_card_details os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.get("https://api.trello.com/1/cards/c1", json={"id": "c1", "name": "Card", "desc": "", "due": None, "dueComplete": False, "url": "", "shortUrl": "", "idList": "l1", "closed": False, "list": {"id": "l1", "name": "List"}, "members": [], "checklists": [], "actions": []}) result = json.loads(trello_card_details(card_id="c1")) assert result["success"] def test_trello_update_card_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_update_card os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.put("https://api.trello.com/1/cards/c1", json={"id": "c1", "name": "New", "desc": "", "due": None}) result = json.loads(trello_update_card(card_id="c1", name="New")) assert result["success"] def test_trello_move_card_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_move_card os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.put("https://api.trello.com/1/cards/c1", json={"id": "c1", "name": "Card", "idList": "l2"}) result = json.loads(trello_move_card(card_id="c1", list_id="l2")) assert result["success"] def test_trello_archive_card_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_archive_card os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.put("https://api.trello.com/1/cards/c1", json={"id": "c1", "name": "Card", "closed": True}) result = json.loads(trello_archive_card(card_id="c1")) assert result["success"] def test_trello_assign_member_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_assign_member os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.post("https://api.trello.com/1/cards/c1/idMembers", json={}, status_code=200) result = json.loads(trello_assign_member(card_id="c1", member_id="m1")) assert result["success"] def test_trello_remove_member_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_remove_member os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.delete("https://api.trello.com/1/cards/c1/idMembers/m1", status_code=200, json={}) result = json.loads(trello_remove_member(card_id="c1", member_id="m1")) assert result["success"] def test_trello_add_comment_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_add_comment os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.post("https://api.trello.com/1/cards/c1/actions/comments", json={"id": "a1", "data": {"text": "Nice"}}) result = json.loads(trello_add_comment(card_id="c1", text="Nice")) assert result["success"] def test_trello_delete_comment_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_delete_comment os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.delete("https://api.trello.com/1/cards/c1/actions/a1/comments", status_code=200, json={}) result = json.loads(trello_delete_comment(card_id="c1", comment_id="a1")) assert result["success"] def test_trello_add_checklist_item_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_add_checklist_item os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.post("https://api.trello.com/1/cards/c1/checklistItems", json={"id": "ci1", "name": "Task", "state": "incomplete", "idChecklist": "cl1"}) result = json.loads(trello_add_checklist_item(card_id="c1", name="Task", checklist_id="cl1")) assert result["success"] def test_trello_toggle_checklist_item_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_toggle_checklist_item os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.put("https://api.trello.com/1/cards/c1/checklistItem/ci1", json={"id": "ci1", "name": "Task", "state": "complete"}) result = json.loads(trello_toggle_checklist_item(card_id="c1", item_id="ci1", checked=True)) assert result["success"] def test_trello_delete_checklist_item_tool(self, requests_mock: Any) -> None: from trello_plugin.tools import trello_delete_checklist_item os.environ["TRELLO_API_KEY"] = "k" os.environ["TRELLO_TOKEN"] = "t" requests_mock.delete("https://api.trello.com/1/cards/c1/checklistItems/ci1", status_code=200, json={}) result = json.loads(trello_delete_checklist_item(card_id="c1", item_id="ci1")) assert result["success"]