From 76ea00268c871da121cb3e673e39f7cec8062512 Mon Sep 17 00:00:00 2001 From: Prabuddha Chakraborty Date: Sun, 24 May 2026 14:04:31 +0530 Subject: [PATCH] Fix typos and move enum stage to avoid conflict --- src/pytfe/models/__init__.py | 4 +-- src/pytfe/models/run_task_request.py | 8 +++--- src/pytfe/models/task_stage.py | 8 +----- src/pytfe/resources/task_result.py | 1 - tests/units/test_run_task_request.py | 40 ++++++++++++++++++++++++++++ tests/units/test_task_stage.py | 11 ++++++-- 6 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 tests/units/test_run_task_request.py diff --git a/src/pytfe/models/__init__.py b/src/pytfe/models/__init__.py index 04c9aaa7..730e2068 100644 --- a/src/pytfe/models/__init__.py +++ b/src/pytfe/models/__init__.py @@ -330,7 +330,7 @@ ) from .run_task_request import ( RunTaskRequest, - RunTaskRequestCapabilitites, + RunTaskRequestCapabilities, ) from .run_trigger import ( RunTrigger, @@ -750,7 +750,7 @@ "RunTaskReadOptions", # Run Task Request "RunTaskRequest", - "RunTaskRequestCapabilitites", + "RunTaskRequestCapabilities", # Task Result "TaskResult", "TaskResultEnforcementLevel", diff --git a/src/pytfe/models/run_task_request.py b/src/pytfe/models/run_task_request.py index b2510460..673cbc60 100644 --- a/src/pytfe/models/run_task_request.py +++ b/src/pytfe/models/run_task_request.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, ConfigDict, Field -class RunTaskRequestCapabilitites(BaseModel): +class RunTaskRequestCapabilities(BaseModel): """Defines the capabilities that the caller supports.""" model_config = ConfigDict(populate_by_name=True) @@ -27,9 +27,9 @@ class RunTaskRequest(BaseModel): access_token: str = Field( ..., alias="access_token", description="The access token for the run task" ) - capabilitites: RunTaskRequestCapabilitites = Field( - default_factory=lambda: RunTaskRequestCapabilitites(outcomes=False), - alias="capabilitites", + capabilities: RunTaskRequestCapabilities = Field( + default_factory=lambda: RunTaskRequestCapabilities(outcomes=False), + alias="capabilities", description="The capabilities that the caller supports", ) configuration_version_download_url: str | None = Field( diff --git a/src/pytfe/models/task_stage.py b/src/pytfe/models/task_stage.py index a5f338ef..a2b76bdc 100644 --- a/src/pytfe/models/task_stage.py +++ b/src/pytfe/models/task_stage.py @@ -10,16 +10,10 @@ from pytfe.models.policy_evaluation import PolicyEvaluation from pytfe.models.run import Run +from pytfe.models.run_task import Stage from pytfe.models.task_result import TaskResult -class Stage(str, Enum): - pre_plan = "pre_plan" - post_plan = "post_plan" - pre_apply = "pre_apply" - post_apply = "post_apply" - - class TaskStageStatus(str, Enum): pending = "pending" running = "running" diff --git a/src/pytfe/resources/task_result.py b/src/pytfe/resources/task_result.py index 737008f0..8f6c05d7 100644 --- a/src/pytfe/resources/task_result.py +++ b/src/pytfe/resources/task_result.py @@ -23,7 +23,6 @@ def read(self, task_result_id: str) -> TaskResult: return self._parse_task_result(data) def _parse_task_result(self, data: dict[str, Any]) -> TaskResult: - attributes = data.get("attributes", {}) attributes["id"] = data.get("id") diff --git a/tests/units/test_run_task_request.py b/tests/units/test_run_task_request.py new file mode 100644 index 00000000..0715cee0 --- /dev/null +++ b/tests/units/test_run_task_request.py @@ -0,0 +1,40 @@ +"""Unit tests for run task webhook request models.""" + +from pytfe.models import RunTaskRequest, RunTaskRequestCapabilities + + +def _run_task_request_payload() -> dict: + return { + "access_token": "token", + "configuration_version_download_url": "https://example.com/cv", + "configuration_version_id": "cv-123", + "is_speculative": False, + "organization_name": "example-org", + "payload_version": 1, + "plan_json_api_url": "https://example.com/plan-json", + "run_app_url": "https://example.com/run", + "run_created_at": "2024-01-01T00:00:00Z", + "run_created_by": "user-123", + "run_id": "run-123", + "run_message": "Queued manually", + "stage": "post_plan", + "task_result_callback_url": "https://example.com/callback", + "task_result_enforcement_level": "mandatory", + "task_result_id": "taskrs-123", + "workspace_app_url": "https://example.com/workspace", + "workspace_id": "ws-123", + "workspace_name": "example-workspace", + } + + +def test_run_task_request_parses_capabilities_from_live_payload(): + payload = _run_task_request_payload() + payload["capabilities"] = {"outcomes": True} + + request = RunTaskRequest.model_validate(payload) + + assert isinstance(request.capabilities, RunTaskRequestCapabilities) + assert request.capabilities.outcomes is True + dumped = request.model_dump(by_alias=True) + assert dumped["capabilities"] == {"outcomes": True} + assert "capabilitites" not in dumped diff --git a/tests/units/test_task_stage.py b/tests/units/test_task_stage.py index 8e7fc738..135af35d 100644 --- a/tests/units/test_task_stage.py +++ b/tests/units/test_task_stage.py @@ -2,6 +2,8 @@ from pytfe.client import TFEClient from pytfe.errors import InvalidTaskStageIDError +from pytfe.models import Stage as ExportedStage +from pytfe.models.run_task import Stage as RunTaskStage from pytfe.models.task_stage import ( Stage, TaskStage, @@ -25,6 +27,11 @@ def test_task_stage_methods_exist(): assert hasattr(client.task_stages, "override") +def test_task_stage_uses_canonical_stage_enum(): + assert Stage is RunTaskStage + assert Stage is ExportedStage + + # InvalidTaskStageIDError tests @@ -69,7 +76,7 @@ def test_task_stage_partial_payload(): {"id": "ts-456", "stage": "pre_plan", "status": "pending"} ) assert ts.id == "ts-456" - assert ts.stage == Stage.pre_plan + assert ts.stage == Stage.PRE_PLAN assert ts.status == TaskStageStatus.pending assert ts.status_timestamps is None assert ts.created_at is None @@ -90,7 +97,7 @@ def test_task_stage_full_payload(): "actions": {"is-overridable": False}, } ) - assert ts.stage == Stage.post_plan + assert ts.stage == Stage.POST_PLAN assert ts.status == TaskStageStatus.passed assert ts.permissions is not None assert ts.permissions.can_override is True