Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion openrelik_api_client/workflows.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2024 Google LLC
# Copyright 2024-2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -158,3 +158,21 @@ def run_workflow(self, folder_id: int, workflow_id: int) -> dict[str, Any] | Non
if response.status_code == 200:
workflow = response.json()
return workflow

def get_workflow_report(self, workflow_id: int) -> dict[str, Any] | None:
"""Retrieves a workflow report.

Args:
workflow_id: The ID of the workflow to retrieve the report from.

Returns:
The workflow report data.

Raises:
HTTPError: If the API request failed.
"""
endpoint = f"{self.api_client.base_url}/workflows/{workflow_id}/report/"
response = self.api_client.session.get(endpoint)
response.raise_for_status()
if response.status_code == 200:
return response.json()
64 changes: 64 additions & 0 deletions tests/workflows_api_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from unittest.mock import MagicMock

from openrelik_api_client.api_client import APIClient, TokenRefreshSession
from openrelik_api_client.workflows import WorkflowsAPI


class TestWorkflowsAPI:
def setup_method(self):
"""Set up test fixtures."""
self.api_client = MagicMock(spec=APIClient)
self.api_client.session = MagicMock(spec=TokenRefreshSession)
self.api_client.base_url = "https://api.example.com/api/v1"
self.workflows_api = WorkflowsAPI(self.api_client)

def test_init(self):
"""Test initialization."""
assert self.workflows_api.api_client == self.api_client

def test_get_workflow_report(self):
"""Test get_workflow_report method."""
workflow_id = 123
mock_response = MagicMock()
mock_response.status_code = 200
expected_report = {"id": workflow_id, "status": "completed", "data": {}}
mock_response.json.return_value = expected_report
self.api_client.session.get.return_value = mock_response

report = self.workflows_api.get_workflow_report(workflow_id)

self.api_client.session.get.assert_called_once_with(
f"{self.api_client.base_url}/workflows/{workflow_id}/report/"
)
mock_response.raise_for_status.assert_called_once()
assert report == expected_report

def test_get_workflow_report_no_content(self):
"""Test get_workflow_report method when no content is returned."""
workflow_id = 456
mock_response = MagicMock()
mock_response.status_code = 204
self.api_client.session.get.return_value = mock_response

report = self.workflows_api.get_workflow_report(workflow_id)

self.api_client.session.get.assert_called_once_with(
f"{self.api_client.base_url}/workflows/{workflow_id}/report/"
)
mock_response.raise_for_status.assert_called_once()
mock_response.json.assert_not_called()
assert report is None