diff --git a/pyproject.toml b/pyproject.toml
index 809dd45..b960d20 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -38,6 +38,7 @@ Tracker = "https://github.com/ibutsu/ibutsu-client-python/issues"
test = [
"pytest",
"pytest-cov",
+ "pytest-mock",
"coverage[toml]",
]
dev = [
diff --git a/test/__init__.py b/test/__init__.py
index e69de29..dd9545f 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -0,0 +1 @@
+"""Test utilities for ibutsu_client tests."""
diff --git a/test/conftest.py b/test/conftest.py
index 439732b..627bf93 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -9,25 +9,15 @@
from ibutsu_client.rest import RESTResponse
-@pytest.fixture
-def mock_api_client(mocker):
- """Create a mock ApiClient for testing API methods."""
- from ibutsu_client.api_client import ApiClient
-
- client = ApiClient()
- mocker.patch.object(client, "call_api")
- return client
-
-
-def create_mock_response(
- data: dict[str, Any] | list[Any] | None = None,
+def _make_mock_response(
+ data: dict[str, Any] | list[Any] | bytes | None = None,
status: int = 200,
headers: dict[str, str] | None = None,
) -> RESTResponse:
- """Create a mock REST response for testing.
+ """Internal helper to create a mock REST response.
Args:
- data: The response data (will be JSON-encoded)
+ data: The response data (will be JSON-encoded unless bytes)
status: HTTP status code
headers: Response headers
@@ -43,7 +33,11 @@ def create_mock_response(
response = Mock(spec=RESTResponse)
response.status = status
response.headers = headers
- response.data = json.dumps(data).encode("utf-8")
+ # Handle bytes data directly without JSON encoding
+ if isinstance(data, bytes):
+ response.data = data
+ else:
+ response.data = json.dumps(data).encode("utf-8")
response.reason = "OK" if status < 400 else "Error"
def mock_read():
@@ -65,6 +59,46 @@ def mock_getheaders() -> dict[str, str]:
@pytest.fixture
-def mock_rest_response():
- """Fixture that provides the create_mock_response function."""
- return create_mock_response
+def mock_api_client():
+ """Create a mock ApiClient for testing API methods."""
+ from ibutsu_client.api_client import ApiClient
+
+ client = ApiClient()
+ client.call_api = Mock()
+ return client
+
+
+@pytest.fixture
+def create_mock_response(request):
+ """Parametrized fixture for creating mock API responses.
+
+ Use with indirect parametrization. Call factory functions directly in the parametrize decorator:
+
+ Example:
+ from test.utils import sample_project_data
+
+ @pytest.mark.parametrize('create_mock_response', [
+ {'data': sample_project_data(name='test', title='Test'), 'status': 201},
+ {'data': {'error': 'not found'}, 'status': 404},
+ ], indirect=True)
+ def test_api_method(self, mocker, create_mock_response):
+ api = SomeApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+ result = api.method()
+ ...
+
+ Args:
+ request.param: Dict with keys:
+ - data: Response data dict/list/bytes
+ - status: HTTP status code (default: 200)
+ - headers: Response headers dict (optional)
+
+ Returns:
+ Mock RESTResponse object ready to use
+ """
+ params = request.param
+ data = params.get("data", {})
+ status = params.get("status", 200)
+ headers = params.get("headers", None)
+
+ return _make_mock_response(data=data, status=status, headers=headers)
diff --git a/test/test_admin_project_management_api.py b/test/test_admin_project_management_api.py
index b159f9e..8acf403 100644
--- a/test/test_admin_project_management_api.py
+++ b/test/test_admin_project_management_api.py
@@ -3,6 +3,8 @@
from urllib.parse import parse_qs, urlparse
from uuid import uuid4
+import pytest
+
from ibutsu_client.api.admin_project_management_api import AdminProjectManagementApi
from ibutsu_client.models.project import Project
from ibutsu_client.models.project_list import ProjectList
@@ -11,19 +13,30 @@
class TestAdminProjectManagementApi:
"""AdminProjectManagementApi Tests"""
- def test_admin_add_project(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "PROJECT_ID_PLACEHOLDER",
+ "name": "New Project",
+ "title": "New Project Title",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_add_project(self, mock_api_client, create_mock_response):
"""Test case for admin_add_project"""
api = AdminProjectManagementApi(api_client=mock_api_client)
project_id = uuid4()
- project_data = {
- "id": str(project_id),
- "name": "New Project",
- "title": "New Project Title",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=project_data, status=201)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual project_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"PROJECT_ID_PLACEHOLDER", str(project_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
new_project = Project(name="New Project", title="New Project Title")
@@ -40,14 +53,18 @@ def test_admin_add_project(self, mock_api_client, mock_rest_response):
assert args[0] == "POST"
assert args[1].endswith("/admin/project")
- def test_admin_delete_project(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 200}],
+ indirect=True,
+ )
+ def test_admin_delete_project(self, mock_api_client, create_mock_response):
"""Test case for admin_delete_project"""
api = AdminProjectManagementApi(api_client=mock_api_client)
project_id = uuid4()
# Mock the API response
- mock_response = mock_rest_response(status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
api.admin_delete_project(id=project_id)
@@ -58,18 +75,29 @@ def test_admin_delete_project(self, mock_api_client, mock_rest_response):
assert args[0] == "DELETE"
assert args[1].endswith(f"/admin/project/{project_id}")
- def test_admin_get_project(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "PROJECT_ID_PLACEHOLDER",
+ "name": "My Project",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_get_project(self, mock_api_client, create_mock_response):
"""Test case for admin_get_project"""
api = AdminProjectManagementApi(api_client=mock_api_client)
project_id = uuid4()
- project_data = {
- "id": str(project_id),
- "name": "My Project",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=project_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual project_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"PROJECT_ID_PLACEHOLDER", str(project_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.admin_get_project(id=project_id)
@@ -85,21 +113,28 @@ def test_admin_get_project(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/admin/project/{project_id}")
- def test_admin_get_project_list(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "projects": [
+ {"id": "00000000-0000-0000-0000-000000000001", "name": "Project 1"},
+ {"id": "00000000-0000-0000-0000-000000000002", "name": "Project 2"},
+ ],
+ "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_get_project_list(self, mock_api_client, create_mock_response):
"""Test case for admin_get_project_list"""
api = AdminProjectManagementApi(api_client=mock_api_client)
- project_list_data = {
- "projects": [
- {"id": str(uuid4()), "name": "Project 1"},
- {"id": str(uuid4()), "name": "Project 2"},
- ],
- "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
- }
-
# Mock the API response
- mock_response = mock_rest_response(data=project_list_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.admin_get_project_list(page=1, page_size=25)
@@ -121,18 +156,29 @@ def test_admin_get_project_list(self, mock_api_client, mock_rest_response):
assert query_params["page"] == ["1"]
assert query_params["pageSize"] == ["25"]
- def test_admin_update_project(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "PROJECT_ID_PLACEHOLDER",
+ "name": "Updated Project",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_update_project(self, mock_api_client, create_mock_response):
"""Test case for admin_update_project"""
api = AdminProjectManagementApi(api_client=mock_api_client)
project_id = uuid4()
- project_data = {
- "id": str(project_id),
- "name": "Updated Project",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=project_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual project_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"PROJECT_ID_PLACEHOLDER", str(project_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
update_project = Project(name="Updated Project")
diff --git a/test/test_admin_user_management_api.py b/test/test_admin_user_management_api.py
index 6424685..2d8db01 100644
--- a/test/test_admin_user_management_api.py
+++ b/test/test_admin_user_management_api.py
@@ -9,50 +9,350 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.admin_user_management_api import AdminUserManagementApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
+from ibutsu_client.models.user import User
+from ibutsu_client.models.user_list import UserList
+from test.utils import sample_pagination_data, sample_user_data
-class TestAdminUserManagementApi(unittest.TestCase):
- """AdminUserManagementApi unit test stubs"""
+class TestAdminUserManagementApi:
+ """AdminUserManagementApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = AdminUserManagementApi()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_user_data(email="newuser@example.com", name="New User"), "status": 201}],
+ indirect=True,
+ )
+ def test_admin_add_user_success(self, mocker, create_mock_response):
+ """Test case for admin_add_user - successfully add a user"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def tearDown(self) -> None:
- pass
+ user = User(email="newuser@example.com", name="New User")
+ result = api.admin_add_user(user=user)
- def test_admin_add_user(self) -> None:
- """Test case for admin_add_user
+ assert isinstance(result, User)
+ assert result.email == "newuser@example.com"
+ assert result.name == "New User"
+ api.api_client.call_api.assert_called_once()
- Administration endpoint to manually add a user. Only accessible to superadmins.
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 403}],
+ indirect=True,
+ )
+ def test_admin_add_user_unauthorized(self, mocker, create_mock_response):
+ """Test case for admin_add_user without superadmin privileges"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_admin_delete_user(self) -> None:
- """Test case for admin_delete_user
+ user = User(email="test@example.com", name="Test")
+ with pytest.raises((ServiceException, Exception)):
+ api.admin_add_user(user=user)
- Administration endpoint to delete a user. Only accessible to superadmins.
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "user already exists"}, "status": 409}],
+ indirect=True,
+ )
+ def test_admin_add_user_conflict(self, mocker, create_mock_response):
+ """Test case for admin_add_user with existing email"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_admin_get_user(self) -> None:
- """Test case for admin_get_user
+ user = User(email="existing@example.com", name="Existing User")
+ with pytest.raises((ServiceException, Exception)):
+ api.admin_add_user(user=user)
- Administration endpoint to return a user. Only accessible to superadmins.
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_user_data(), "status": 201}],
+ indirect=True,
+ )
+ def test_admin_add_user_with_http_info(self, mocker, create_mock_response):
+ """Test case for admin_add_user_with_http_info"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_admin_get_user_list(self) -> None:
- """Test case for admin_get_user_list
+ user = User(email="test@example.com", name="Test User")
+ result = api.admin_add_user_with_http_info(user=user)
- Administration endpoint to return a list of users. Only accessible to superadmins.
- """
+ assert result.status_code == 201
+ assert isinstance(result.data, User)
- def test_admin_update_user(self) -> None:
- """Test case for admin_update_user
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 204}],
+ indirect=True,
+ )
+ def test_admin_delete_user_success(self, mocker, create_mock_response):
+ """Test case for admin_delete_user - successfully delete a user"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- Administration endpoint to update a user. Only accessible to superadmins.
- """
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ api.admin_delete_user(id=user_id)
+ # 204 No Content typically returns None
+ api.api_client.call_api.assert_called_once()
-if __name__ == "__main__":
- unittest.main()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_admin_delete_user_not_found(self, mocker, create_mock_response):
+ """Test case for admin_delete_user with non-existent user"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.admin_delete_user(id=user_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "forbidden"}, "status": 403}],
+ indirect=True,
+ )
+ def test_admin_delete_user_forbidden(self, mocker, create_mock_response):
+ """Test case for admin_delete_user without superadmin privileges"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises((ServiceException, Exception)):
+ api.admin_delete_user(id=user_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 204}],
+ indirect=True,
+ )
+ def test_admin_delete_user_with_http_info(self, mocker, create_mock_response):
+ """Test case for admin_delete_user_with_http_info"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.admin_delete_user_with_http_info(id=user_id)
+
+ assert result.status_code == 204
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_user_data(email="admin@example.com", is_superadmin=True),
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_get_user_success(self, mocker, create_mock_response):
+ """Test case for admin_get_user - retrieve a single user"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.admin_get_user(id=user_id)
+
+ assert isinstance(result, User)
+ assert result.email == "admin@example.com"
+ assert result.is_superadmin is True
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_admin_get_user_not_found(self, mocker, create_mock_response):
+ """Test case for admin_get_user with non-existent user"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.admin_get_user(id=user_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_user_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_admin_get_user_with_http_info(self, mocker, create_mock_response):
+ """Test case for admin_get_user_with_http_info"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.admin_get_user_with_http_info(id=user_id)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, User)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "users": [
+ sample_user_data(email="user1@example.com", name="User One"),
+ sample_user_data(email="user2@example.com", name="User Two"),
+ ],
+ "pagination": sample_pagination_data(total_items=2),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_get_user_list_success(self, mocker, create_mock_response):
+ """Test case for admin_get_user_list - retrieve list of users"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.admin_get_user_list()
+
+ assert isinstance(result, UserList)
+ assert len(result.users) == 2
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "users": [sample_user_data()],
+ "pagination": sample_pagination_data(page=2, page_size=10, total_items=15),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_get_user_list_with_pagination(self, mocker, create_mock_response):
+ """Test case for admin_get_user_list with pagination parameters"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.admin_get_user_list(page=2, page_size=10)
+
+ assert isinstance(result, UserList)
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "users": [sample_user_data(is_superadmin=True)],
+ "pagination": sample_pagination_data(total_items=1),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_get_user_list_with_filters(self, mocker, create_mock_response):
+ """Test case for admin_get_user_list with filter parameters"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.admin_get_user_list(filter=["is_superadmin=true"])
+
+ assert isinstance(result, UserList)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "users": [],
+ "pagination": sample_pagination_data(),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_get_user_list_with_http_info(self, mocker, create_mock_response):
+ """Test case for admin_get_user_list_with_http_info"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.admin_get_user_list_with_http_info()
+
+ assert result.status_code == 200
+ assert isinstance(result.data, UserList)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_user_data(email="updated@example.com", is_superadmin=True),
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_admin_update_user_success(self, mocker, create_mock_response):
+ """Test case for admin_update_user - successfully update a user"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ user = User(email="updated@example.com", is_superadmin=True)
+ result = api.admin_update_user(id=user_id, user=user)
+
+ assert isinstance(result, User)
+ assert result.is_superadmin is True
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_admin_update_user_not_found(self, mocker, create_mock_response):
+ """Test case for admin_update_user with non-existent user"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ user = User(email="test@example.com", name="Test")
+ with pytest.raises(NotFoundException):
+ api.admin_update_user(id=user_id, user=user)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_user_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_admin_update_user_with_http_info(self, mocker, create_mock_response):
+ """Test case for admin_update_user_with_http_info"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ user = User(email="test@example.com", name="Test")
+ result = api.admin_update_user_with_http_info(id=user_id, user=user)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, User)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "internal error"}, "status": 500}],
+ indirect=True,
+ )
+ def test_admin_update_user_server_error(self, mocker, create_mock_response):
+ """Test case for admin_update_user with server error"""
+ api = AdminUserManagementApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ user_id = "550e8400-e29b-41d4-a716-446655440000"
+ user = User(email="test@example.com", name="Test")
+ with pytest.raises(ServiceException):
+ api.admin_update_user(id=user_id, user=user)
diff --git a/test/test_artifact_api.py b/test/test_artifact_api.py
index b879858..2893d3a 100644
--- a/test/test_artifact_api.py
+++ b/test/test_artifact_api.py
@@ -2,6 +2,8 @@
from uuid import uuid4
+import pytest
+
from ibutsu_client.api.artifact_api import ArtifactApi
from ibutsu_client.models.artifact import Artifact
from ibutsu_client.models.artifact_list import ArtifactList
@@ -10,21 +12,36 @@
class TestArtifactApi:
"""ArtifactApi Tests"""
- def test_get_artifact_list(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "artifacts": [
+ {
+ "id": "00000000-0000-0000-0000-000000000001",
+ "filename": "test1.txt",
+ "mime_type": "text/plain",
+ },
+ {
+ "id": "00000000-0000-0000-0000-000000000002",
+ "filename": "test2.png",
+ "mime_type": "image/png",
+ },
+ ],
+ "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_artifact_list(self, mock_api_client, create_mock_response):
"""Test case for get_artifact_list"""
api = ArtifactApi(api_client=mock_api_client)
- artifact_list_data = {
- "artifacts": [
- {"id": str(uuid4()), "filename": "test1.txt", "mime_type": "text/plain"},
- {"id": str(uuid4()), "filename": "test2.png", "mime_type": "image/png"},
- ],
- "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
- }
-
# Mock the API response
- mock_response = mock_rest_response(data=artifact_list_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_artifact_list(page=1, page_size=25)
@@ -43,19 +60,30 @@ def test_get_artifact_list(self, mock_api_client, mock_rest_response):
assert "page=1" in args[1]
assert "pageSize=25" in args[1]
- def test_get_artifact(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "ARTIFACT_ID_PLACEHOLDER",
+ "filename": "test.txt",
+ "mime_type": "text/plain",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_artifact(self, mock_api_client, create_mock_response):
"""Test case for get_artifact"""
api = ArtifactApi(api_client=mock_api_client)
artifact_id = uuid4()
- artifact_data = {
- "id": str(artifact_id),
- "filename": "test.txt",
- "mime_type": "text/plain",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=artifact_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual artifact_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"ARTIFACT_ID_PLACEHOLDER", str(artifact_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_artifact(id=artifact_id)
@@ -71,17 +99,19 @@ def test_get_artifact(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/artifact/{artifact_id}")
- def test_download_artifact(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": b"file content", "status": 200}],
+ indirect=True,
+ )
+ def test_download_artifact(self, mock_api_client, create_mock_response):
"""Test case for download_artifact"""
api = ArtifactApi(api_client=mock_api_client)
artifact_id = uuid4()
file_content = b"file content"
# Mock the API response
- # Note: download_artifact returns bytearray, so we mock the raw data
- mock_response = mock_rest_response(status=200)
- mock_response.data = file_content
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.download_artifact(id=artifact_id)
@@ -95,16 +125,19 @@ def test_download_artifact(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/artifact/{artifact_id}/download")
- def test_view_artifact(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": b"file content", "status": 200}],
+ indirect=True,
+ )
+ def test_view_artifact(self, mock_api_client, create_mock_response):
"""Test case for view_artifact"""
api = ArtifactApi(api_client=mock_api_client)
artifact_id = uuid4()
file_content = b"file content"
# Mock the API response
- mock_response = mock_rest_response(status=200)
- mock_response.data = file_content
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.view_artifact(id=artifact_id)
@@ -118,23 +151,37 @@ def test_view_artifact(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/artifact/{artifact_id}/view")
- def test_upload_artifact(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "ARTIFACT_ID_PLACEHOLDER",
+ "filename": "test.txt",
+ "result_id": None,
+ "run_id": "RUN_ID_PLACEHOLDER",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_upload_artifact(self, mock_api_client, create_mock_response):
"""Test case for upload_artifact"""
api = ArtifactApi(api_client=mock_api_client)
run_id = uuid4()
+ artifact_id = uuid4()
filename = "test.txt"
file_content = b"content"
- artifact_data = {
- "id": str(uuid4()),
- "filename": filename,
- "result_id": None,
- "run_id": str(run_id),
- }
-
- # Mock the API response
- mock_response = mock_rest_response(data=artifact_data, status=201)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual IDs
+ create_mock_response.data = create_mock_response.data.replace(
+ b"ARTIFACT_ID_PLACEHOLDER", str(artifact_id).encode()
+ )
+ create_mock_response.data = create_mock_response.data.replace(
+ b"RUN_ID_PLACEHOLDER", str(run_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.upload_artifact(filename=filename, file=file_content, run_id=run_id)
@@ -161,14 +208,18 @@ def test_upload_artifact(self, mock_api_client, mock_rest_response):
)
assert file_found
- def test_delete_artifact(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 200}],
+ indirect=True,
+ )
+ def test_delete_artifact(self, mock_api_client, create_mock_response):
"""Test case for delete_artifact"""
api = ArtifactApi(api_client=mock_api_client)
artifact_id = uuid4()
# Mock the API response
- mock_response = mock_rest_response(status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
api.delete_artifact(id=artifact_id)
diff --git a/test/test_dashboard_api.py b/test/test_dashboard_api.py
index a6cb58d..c8702c3 100644
--- a/test/test_dashboard_api.py
+++ b/test/test_dashboard_api.py
@@ -3,6 +3,8 @@
from urllib.parse import parse_qs, urlparse
from uuid import uuid4
+import pytest
+
from ibutsu_client.api.dashboard_api import DashboardApi
from ibutsu_client.models.dashboard import Dashboard
from ibutsu_client.models.dashboard_list import DashboardList
@@ -11,19 +13,30 @@
class TestDashboardApi:
"""DashboardApi Tests"""
- def test_add_dashboard(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "DASHBOARD_ID_PLACEHOLDER",
+ "title": "New Dashboard",
+ "description": "Description",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_dashboard(self, mock_api_client, create_mock_response):
"""Test case for add_dashboard"""
api = DashboardApi(api_client=mock_api_client)
dashboard_id = uuid4()
- dashboard_data = {
- "id": str(dashboard_id),
- "title": "New Dashboard",
- "description": "Description",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=dashboard_data, status=201)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual dashboard_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"DASHBOARD_ID_PLACEHOLDER", str(dashboard_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
new_dashboard = Dashboard(title="New Dashboard", description="Description")
@@ -40,14 +53,18 @@ def test_add_dashboard(self, mock_api_client, mock_rest_response):
assert args[0] == "POST"
assert args[1].endswith("/dashboard")
- def test_delete_dashboard(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 200}],
+ indirect=True,
+ )
+ def test_delete_dashboard(self, mock_api_client, create_mock_response):
"""Test case for delete_dashboard"""
api = DashboardApi(api_client=mock_api_client)
dashboard_id = uuid4()
# Mock the API response
- mock_response = mock_rest_response(status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
api.delete_dashboard(id=dashboard_id)
@@ -58,18 +75,29 @@ def test_delete_dashboard(self, mock_api_client, mock_rest_response):
assert args[0] == "DELETE"
assert args[1].endswith(f"/dashboard/{dashboard_id}")
- def test_get_dashboard(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "DASHBOARD_ID_PLACEHOLDER",
+ "title": "My Dashboard",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_dashboard(self, mock_api_client, create_mock_response):
"""Test case for get_dashboard"""
api = DashboardApi(api_client=mock_api_client)
dashboard_id = uuid4()
- dashboard_data = {
- "id": str(dashboard_id),
- "title": "My Dashboard",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=dashboard_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual dashboard_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"DASHBOARD_ID_PLACEHOLDER", str(dashboard_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_dashboard(id=dashboard_id)
@@ -85,21 +113,28 @@ def test_get_dashboard(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/dashboard/{dashboard_id}")
- def test_get_dashboard_list(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "dashboards": [
+ {"id": "00000000-0000-0000-0000-000000000001", "title": "Dashboard 1"},
+ {"id": "00000000-0000-0000-0000-000000000002", "title": "Dashboard 2"},
+ ],
+ "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_dashboard_list(self, mock_api_client, create_mock_response):
"""Test case for get_dashboard_list"""
api = DashboardApi(api_client=mock_api_client)
- dashboard_list_data = {
- "dashboards": [
- {"id": str(uuid4()), "title": "Dashboard 1"},
- {"id": str(uuid4()), "title": "Dashboard 2"},
- ],
- "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
- }
-
# Mock the API response
- mock_response = mock_rest_response(data=dashboard_list_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_dashboard_list(page=1, page_size=25)
@@ -121,18 +156,29 @@ def test_get_dashboard_list(self, mock_api_client, mock_rest_response):
assert query_params["page"] == ["1"]
assert query_params["pageSize"] == ["25"]
- def test_update_dashboard(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "DASHBOARD_ID_PLACEHOLDER",
+ "title": "Updated Dashboard",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_update_dashboard(self, mock_api_client, create_mock_response):
"""Test case for update_dashboard"""
api = DashboardApi(api_client=mock_api_client)
dashboard_id = uuid4()
- dashboard_data = {
- "id": str(dashboard_id),
- "title": "Updated Dashboard",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=dashboard_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual dashboard_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"DASHBOARD_ID_PLACEHOLDER", str(dashboard_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
update_dashboard = Dashboard(title="Updated Dashboard")
diff --git a/test/test_group_api.py b/test/test_group_api.py
index 638f8a7..d286ac5 100644
--- a/test/test_group_api.py
+++ b/test/test_group_api.py
@@ -9,44 +9,280 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.group_api import GroupApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
+from ibutsu_client.models.group import Group
+from ibutsu_client.models.group_list import GroupList
+from test.utils import sample_group_data, sample_pagination_data
-class TestGroupApi(unittest.TestCase):
- """GroupApi unit test stubs"""
+class TestGroupApi:
+ """GroupApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = GroupApi()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_group_data(name="engineering-team"), "status": 201}],
+ indirect=True,
+ )
+ def test_add_group_success(self, mocker, create_mock_response):
+ """Test case for add_group - successfully create a new group"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def tearDown(self) -> None:
- pass
+ group = Group(name="engineering-team")
+ result = api.add_group(group=group)
- def test_add_group(self) -> None:
- """Test case for add_group
+ assert isinstance(result, Group)
+ assert result.name == "engineering-team"
+ api.api_client.call_api.assert_called_once()
- Create a new group
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 401}],
+ indirect=True,
+ )
+ def test_add_group_unauthorized(self, mocker, create_mock_response):
+ """Test case for add_group without proper authentication"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_get_group(self) -> None:
- """Test case for get_group
+ group = Group(name="test-group")
+ with pytest.raises((ServiceException, Exception)):
+ api.add_group(group=group)
- Get a group
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "group already exists"}, "status": 409}],
+ indirect=True,
+ )
+ def test_add_group_conflict(self, mocker, create_mock_response):
+ """Test case for add_group with existing group name"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_get_group_list(self) -> None:
- """Test case for get_group_list
+ group = Group(name="existing-group")
+ with pytest.raises((ServiceException, Exception)):
+ api.add_group(group=group)
- Get a list of groups
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_group_data(name="new-team"), "status": 201}],
+ indirect=True,
+ )
+ def test_add_group_with_http_info(self, mocker, create_mock_response):
+ """Test case for add_group_with_http_info"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_update_group(self) -> None:
- """Test case for update_group
+ group = Group(name="new-team")
+ result = api.add_group_with_http_info(group=group)
- Update a group
- """
+ assert result.status_code == 201
+ assert isinstance(result.data, Group)
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_group_data(name="qa-team"), "status": 200}],
+ indirect=True,
+ )
+ def test_get_group_success(self, mocker, create_mock_response):
+ """Test case for get_group - retrieve a single group"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
-if __name__ == "__main__":
- unittest.main()
+ group_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_group(id=group_id)
+
+ assert isinstance(result, Group)
+ assert result.name == "qa-team"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_get_group_not_found(self, mocker, create_mock_response):
+ """Test case for get_group with non-existent group"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ group_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.get_group(id=group_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_group_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_get_group_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_group_with_http_info"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ group_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_group_with_http_info(id=group_id)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, Group)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "groups": [
+ sample_group_data(name="team-alpha"),
+ sample_group_data(name="team-beta"),
+ ],
+ "pagination": sample_pagination_data(total_items=2),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_group_list_success(self, mocker, create_mock_response):
+ """Test case for get_group_list - retrieve list of groups"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_group_list()
+
+ assert isinstance(result, GroupList)
+ assert len(result.groups) == 2
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "groups": [sample_group_data()],
+ "pagination": sample_pagination_data(page=2, page_size=10),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_group_list_with_pagination(self, mocker, create_mock_response):
+ """Test case for get_group_list with pagination parameters"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_group_list(page=2, page_size=10)
+
+ assert isinstance(result, GroupList)
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "groups": [],
+ "pagination": sample_pagination_data(total_items=0),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_group_list_empty(self, mocker, create_mock_response):
+ """Test case for get_group_list with no groups"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_group_list()
+
+ assert isinstance(result, GroupList)
+ assert len(result.groups) == 0
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "groups": [],
+ "pagination": sample_pagination_data(),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_group_list_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_group_list_with_http_info"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_group_list_with_http_info()
+
+ assert result.status_code == 200
+ assert isinstance(result.data, GroupList)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_group_data(name="updated-team-name"), "status": 200}],
+ indirect=True,
+ )
+ def test_update_group_success(self, mocker, create_mock_response):
+ """Test case for update_group - successfully update a group"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ group_id = "550e8400-e29b-41d4-a716-446655440000"
+ group = Group(name="updated-team-name")
+ result = api.update_group(id=group_id, group=group)
+
+ assert isinstance(result, Group)
+ assert result.name == "updated-team-name"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_update_group_not_found(self, mocker, create_mock_response):
+ """Test case for update_group with non-existent group"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ group_id = "550e8400-e29b-41d4-a716-446655440000"
+ group = Group(name="test-group")
+ with pytest.raises(NotFoundException):
+ api.update_group(id=group_id, group=group)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_group_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_update_group_with_http_info(self, mocker, create_mock_response):
+ """Test case for update_group_with_http_info"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ group_id = "550e8400-e29b-41d4-a716-446655440000"
+ group = Group(name="test-group")
+ result = api.update_group_with_http_info(id=group_id, group=group)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, Group)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "internal error"}, "status": 500}],
+ indirect=True,
+ )
+ def test_update_group_server_error(self, mocker, create_mock_response):
+ """Test case for update_group with server error"""
+ api = GroupApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ group_id = "550e8400-e29b-41d4-a716-446655440000"
+ group = Group(name="test-group")
+ with pytest.raises(ServiceException):
+ api.update_group(id=group_id, group=group)
diff --git a/test/test_health_api.py b/test/test_health_api.py
index f8a8a31..0094771 100644
--- a/test/test_health_api.py
+++ b/test/test_health_api.py
@@ -15,26 +15,26 @@
from ibutsu_client.exceptions import ServiceException
from ibutsu_client.models.health import Health
from ibutsu_client.models.health_info import HealthInfo
-from test.conftest import create_mock_response
class TestHealthApi:
"""HealthApi unit tests"""
- def test_get_database_health(self, mocker):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"status": "ok", "message": "Database is healthy"}, "status": 200}],
+ indirect=True,
+ )
+ def test_get_database_health(self, mocker, create_mock_response):
"""Test case for get_database_health
Get a health report for the database
"""
- # Mock response data
- response_data = {"status": "ok", "message": "Database is healthy"}
-
# Create API instance
api = HealthApi()
# Mock the call_api method
- mock_response = create_mock_response(response_data, status=200)
- mocker.patch.object(api.api_client, "call_api", return_value=mock_response)
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
# Call the method
result = api.get_database_health()
@@ -47,13 +47,15 @@ def test_get_database_health(self, mocker):
# Verify call_api was called
api.api_client.call_api.assert_called_once()
- def test_get_database_health_error(self, mocker):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"status": "error", "message": "Database connection failed"}, "status": 500}],
+ indirect=True,
+ )
+ def test_get_database_health_error(self, mocker, create_mock_response):
"""Test case for get_database_health with error response"""
- response_data = {"status": "error", "message": "Database connection failed"}
-
api = HealthApi()
- mock_response = create_mock_response(response_data, status=500)
- mocker.patch.object(api.api_client, "call_api", return_value=mock_response)
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
# 500 errors raise ServiceException
with pytest.raises(ServiceException) as exc_info:
@@ -62,16 +64,18 @@ def test_get_database_health_error(self, mocker):
assert exc_info.value.status == 500
assert "error" in str(exc_info.value.body).lower()
- def test_get_health(self, mocker):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"status": "ok", "message": "Service is healthy"}, "status": 200}],
+ indirect=True,
+ )
+ def test_get_health(self, mocker, create_mock_response):
"""Test case for get_health
Get a general health report
"""
- response_data = {"status": "ok", "message": "Service is healthy"}
-
api = HealthApi()
- mock_response = create_mock_response(response_data, status=200)
- mocker.patch.object(api.api_client, "call_api", return_value=mock_response)
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
result = api.get_health()
@@ -79,20 +83,27 @@ def test_get_health(self, mocker):
assert result.status == "ok"
assert result.message == "Service is healthy"
- def test_get_health_info(self, mocker):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "frontend": "https://ibutsu.example.com",
+ "backend": "https://api.ibutsu.example.com",
+ "api_ui": "https://api.ibutsu.example.com/docs",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_health_info(self, mocker, create_mock_response):
"""Test case for get_health_info
Get information about the server
"""
- response_data = {
- "frontend": "https://ibutsu.example.com",
- "backend": "https://api.ibutsu.example.com",
- "api_ui": "https://api.ibutsu.example.com/docs",
- }
-
api = HealthApi()
- mock_response = create_mock_response(response_data, status=200)
- mocker.patch.object(api.api_client, "call_api", return_value=mock_response)
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
result = api.get_health_info()
@@ -101,17 +112,24 @@ def test_get_health_info(self, mocker):
assert result.backend == "https://api.ibutsu.example.com"
assert result.api_ui == "https://api.ibutsu.example.com/docs"
- def test_get_health_info_with_http_info(self, mocker):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "frontend": "https://ibutsu.example.com",
+ "backend": "https://api.ibutsu.example.com",
+ "api_ui": "https://api.ibutsu.example.com/docs",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_health_info_with_http_info(self, mocker, create_mock_response):
"""Test case for get_health_info_with_http_info"""
- response_data = {
- "frontend": "https://ibutsu.example.com",
- "backend": "https://api.ibutsu.example.com",
- "api_ui": "https://api.ibutsu.example.com/docs",
- }
-
api = HealthApi()
- mock_response = create_mock_response(response_data, status=200)
- mocker.patch.object(api.api_client, "call_api", return_value=mock_response)
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
result = api.get_health_info_with_http_info()
diff --git a/test/test_import_api.py b/test/test_import_api.py
index 4bd70fd..a6f3edf 100644
--- a/test/test_import_api.py
+++ b/test/test_import_api.py
@@ -9,32 +9,283 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.import_api import ImportApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
+from ibutsu_client.models.model_import import ModelImport
-class TestImportApi(unittest.TestCase):
- """ImportApi unit test stubs"""
+class TestImportApi:
+ """ImportApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = ImportApi()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "test_results.xml",
+ "format": "junit",
+ "status": "pending",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_import_success(self, mocker, create_mock_response):
+ """Test case for add_import - successfully import a file"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def tearDown(self) -> None:
- pass
+ # Mock file upload - import_file as tuple (filename, content)
+ result = api.add_import(
+ import_file=("test_results.xml", b"test content"),
+ )
- def test_add_import(self) -> None:
- """Test case for add_import
+ assert isinstance(result, ModelImport)
+ assert result.filename == "test_results.xml"
+ assert result.format == "junit"
+ api.api_client.call_api.assert_called_once()
- Import a file into Ibutsu. This can be either a JUnit XML file, or an Ibutsu archive
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "results.xml",
+ "format": "junit",
+ "project": "test-project",
+ "status": "pending",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_import_with_project(self, mocker, create_mock_response):
+ """Test case for add_import with project parameter"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_get_import(self) -> None:
- """Test case for get_import
+ result = api.add_import(
+ import_file=("results.xml", b"test"),
+ project="test-project",
+ )
- Get the status of an import
- """
+ assert isinstance(result, ModelImport)
+ assert result.filename == "results.xml"
+ api.api_client.call_api.assert_called_once()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "archive.tar.gz",
+ "format": "ibutsu",
+ "status": "pending",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_import_archive_format(self, mocker, create_mock_response):
+ """Test case for add_import with Ibutsu archive format"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
-if __name__ == "__main__":
- unittest.main()
+ result = api.add_import(
+ import_file=("archive.tar.gz", b"binary archive content"),
+ )
+
+ assert isinstance(result, ModelImport)
+ assert result.format == "ibutsu"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "invalid file format"}, "status": 400}],
+ indirect=True,
+ )
+ def test_add_import_invalid_file(self, mocker, create_mock_response):
+ """Test case for add_import with invalid file"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ with pytest.raises((ServiceException, Exception)):
+ api.add_import(import_file=("invalid.txt", b"invalid content"))
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 401}],
+ indirect=True,
+ )
+ def test_add_import_unauthorized(self, mocker, create_mock_response):
+ """Test case for add_import without authentication"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ with pytest.raises((ServiceException, Exception)):
+ api.add_import(import_file=("test.xml", b"content"))
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "test.xml",
+ "status": "pending",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_import_with_http_info(self, mocker, create_mock_response):
+ """Test case for add_import_with_http_info"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.add_import_with_http_info(
+ import_file=("test.xml", b"content"),
+ )
+
+ assert result.status_code == 201
+ assert isinstance(result.data, ModelImport)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "test_results.xml",
+ "format": "junit",
+ "status": "done",
+ "run_id": "660e8400-e29b-41d4-a716-446655440000",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_import_success(self, mocker, create_mock_response):
+ """Test case for get_import - retrieve import status"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ import_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_import(id=import_id)
+
+ assert isinstance(result, ModelImport)
+ assert result.status == "done"
+ assert result.run_id is not None
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "test.xml",
+ "status": "pending",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_import_pending_status(self, mocker, create_mock_response):
+ """Test case for get_import with pending status"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ import_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_import(id=import_id)
+
+ assert isinstance(result, ModelImport)
+ assert result.status == "pending"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "test.xml",
+ "status": "running",
+ "format": "junit",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_import_running_status(self, mocker, create_mock_response):
+ """Test case for get_import with running status"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ import_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_import(id=import_id)
+
+ assert isinstance(result, ModelImport)
+ assert result.status == "running"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_get_import_not_found(self, mocker, create_mock_response):
+ """Test case for get_import with non-existent import"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ import_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.get_import(id=import_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "filename": "test.xml",
+ "status": "done",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_import_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_import_with_http_info"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ import_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_import_with_http_info(id=import_id)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, ModelImport)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "internal error"}, "status": 500}],
+ indirect=True,
+ )
+ def test_get_import_server_error(self, mocker, create_mock_response):
+ """Test case for get_import with server error"""
+ api = ImportApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ import_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(ServiceException):
+ api.get_import(id=import_id)
diff --git a/test/test_login_api.py b/test/test_login_api.py
index f68ef31..5a544e2 100644
--- a/test/test_login_api.py
+++ b/test/test_login_api.py
@@ -9,44 +9,398 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.login_api import LoginApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
+from ibutsu_client.models.login_config import LoginConfig
+from ibutsu_client.models.login_support import LoginSupport
+from ibutsu_client.models.login_token import LoginToken
-class TestLoginApi(unittest.TestCase):
- """LoginApi unit test stubs"""
+class TestLoginApi:
+ """LoginApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = LoginApi()
+ def test_activate_success(self, mocker):
+ """Test case for activate with successful activation"""
+ api = LoginApi()
+ from ibutsu_client.api_response import ApiResponse
- def tearDown(self) -> None:
- pass
+ # Mock response_deserialize to return ApiResponse with None data (302 redirect)
+ mock_api_response = ApiResponse(status_code=302, data=None, headers={}, raw_data=b"")
+ mocker.patch.object(api.api_client, "response_deserialize", return_value=mock_api_response)
+ mocker.patch.object(api.api_client, "call_api")
- def test_activate(self) -> None:
- """Test case for activate"""
+ # Should not raise exception for 302 redirect
+ result = api.activate(activation_code="test-activation-code")
+ assert result is None
+ api.api_client.call_api.assert_called_once()
- def test_auth(self) -> None:
- """Test case for auth"""
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_activate_not_found(self, mocker, create_mock_response):
+ """Test case for activate with invalid activation code"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_config(self) -> None:
- """Test case for config"""
+ with pytest.raises(NotFoundException):
+ api.activate(activation_code="invalid-code")
- def test_login(self) -> None:
- """Test case for login"""
+ def test_activate_with_http_info(self, mocker):
+ """Test case for activate_with_http_info"""
+ api = LoginApi()
+ from ibutsu_client.api_response import ApiResponse
- def test_recover(self) -> None:
- """Test case for recover"""
+ # Mock response_deserialize to return ApiResponse with None data (302 redirect)
+ mock_api_response = ApiResponse(status_code=302, data=None, headers={}, raw_data=b"")
+ mocker.patch.object(api.api_client, "response_deserialize", return_value=mock_api_response)
+ mocker.patch.object(api.api_client, "call_api")
- def test_register(self) -> None:
- """Test case for register"""
+ result = api.activate_with_http_info(activation_code="test-code")
+ assert result.status_code == 302
+ assert result.data is None
- def test_reset_password(self) -> None:
- """Test case for reset_password"""
+ def test_auth_success(self, mocker):
+ """Test case for auth - redirects to OAuth provider"""
+ api = LoginApi()
+ from ibutsu_client.api_response import ApiResponse
- def test_support(self) -> None:
- """Test case for support"""
+ # auth() returns None (302 redirect to OAuth provider)
+ mock_api_response = ApiResponse(status_code=302, data=None, headers={}, raw_data=b"")
+ mocker.patch.object(api.api_client, "response_deserialize", return_value=mock_api_response)
+ mocker.patch.object(api.api_client, "call_api")
+ result = api.auth(provider="oidc")
+ assert result is None
+ api.api_client.call_api.assert_called_once()
-if __name__ == "__main__":
- unittest.main()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "invalid provider"}, "status": 400}],
+ indirect=True,
+ )
+ def test_auth_unauthorized(self, mocker, create_mock_response):
+ """Test case for auth with invalid provider"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ with pytest.raises(
+ (ServiceException, Exception)
+ ): # Should raise appropriate auth exception
+ api.auth(provider="invalid")
+
+ def test_auth_with_http_info(self, mocker):
+ """Test case for auth_with_http_info - redirects to OAuth provider"""
+ api = LoginApi()
+ from ibutsu_client.api_response import ApiResponse
+
+ # auth() returns None (302 redirect to OAuth provider)
+ mock_api_response = ApiResponse(status_code=302, data=None, headers={}, raw_data=b"")
+ mocker.patch.object(api.api_client, "response_deserialize", return_value=mock_api_response)
+ mocker.patch.object(api.api_client, "call_api")
+
+ result = api.auth_with_http_info(provider="oidc")
+ assert result.status_code == 302
+ assert result.data is None
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "client_id": "test-client-id",
+ "redirect_uri": "https://example.com/callback",
+ "scope": "openid profile email",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_config_success(self, mocker, create_mock_response):
+ """Test case for config - get login configuration"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.config(provider="oidc")
+ assert isinstance(result, LoginConfig)
+ assert result.client_id == "test-client-id"
+ assert result.redirect_uri == "https://example.com/callback"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"client_id": "test-client"}, "status": 200}],
+ indirect=True,
+ )
+ def test_config_with_http_info(self, mocker, create_mock_response):
+ """Test case for config_with_http_info"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.config_with_http_info(provider="oidc")
+ assert result.status_code == 200
+ assert isinstance(result.data, LoginConfig)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "token": "jwt-token-here",
+ "refresh_token": "refresh-token-here",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_login_success(self, mocker, create_mock_response):
+ """Test case for login with valid credentials"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.credentials import Credentials
+
+ credentials = Credentials(email="test@example.com", password="password123")
+ result = api.login(credentials=credentials)
+ assert isinstance(result, LoginToken)
+ assert result.token == "jwt-token-here"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "invalid credentials"}, "status": 401}],
+ indirect=True,
+ )
+ def test_login_invalid_credentials(self, mocker, create_mock_response):
+ """Test case for login with invalid credentials"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.credentials import Credentials
+
+ credentials = Credentials(email="wrong@example.com", password="wrongpass")
+ with pytest.raises((ServiceException, Exception)):
+ api.login(credentials=credentials)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"token": "test-token"}, "status": 200}],
+ indirect=True,
+ )
+ def test_login_with_http_info(self, mocker, create_mock_response):
+ """Test case for login_with_http_info"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.credentials import Credentials
+
+ credentials = Credentials(email="test@example.com", password="pass")
+ result = api.login_with_http_info(credentials=credentials)
+ assert result.status_code == 200
+ assert isinstance(result.data, LoginToken)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 200}],
+ indirect=True,
+ )
+ def test_recover_success(self, mocker, create_mock_response):
+ """Test case for recover - initiate password recovery"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_recovery import AccountRecovery
+
+ recovery_data = AccountRecovery(email="test@example.com")
+ api.recover(account_recovery=recovery_data)
+ # Method should complete without raising exception
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "user not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_recover_not_found(self, mocker, create_mock_response):
+ """Test case for recover with non-existent email"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_recovery import AccountRecovery
+
+ recovery_data = AccountRecovery(email="nonexistent@example.com")
+ with pytest.raises(NotFoundException):
+ api.recover(account_recovery=recovery_data)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 200}],
+ indirect=True,
+ )
+ def test_recover_with_http_info(self, mocker, create_mock_response):
+ """Test case for recover_with_http_info"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_recovery import AccountRecovery
+
+ recovery_data = AccountRecovery(email="test@example.com")
+ result = api.recover_with_http_info(account_recovery=recovery_data)
+ assert result.status_code == 200
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"message": "Registration successful"}, "status": 201}],
+ indirect=True,
+ )
+ def test_register_success(self, mocker, create_mock_response):
+ """Test case for register with valid registration data"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_registration import AccountRegistration
+
+ registration = AccountRegistration(
+ email="newuser@example.com", password="securepass123", name="New User"
+ )
+ api.register(account_registration=registration)
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "email already exists"}, "status": 409}],
+ indirect=True,
+ )
+ def test_register_conflict(self, mocker, create_mock_response):
+ """Test case for register with existing email"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_registration import AccountRegistration
+
+ registration = AccountRegistration(
+ email="existing@example.com", password="pass123", name="User"
+ )
+ with pytest.raises((ServiceException, Exception)): # Should raise conflict exception
+ api.register(account_registration=registration)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"message": "success"}, "status": 201}],
+ indirect=True,
+ )
+ def test_register_with_http_info(self, mocker, create_mock_response):
+ """Test case for register_with_http_info"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_registration import AccountRegistration
+
+ registration = AccountRegistration(email="test@example.com", password="pass", name="Test")
+ result = api.register_with_http_info(account_registration=registration)
+ assert result.status_code == 201
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 200}],
+ indirect=True,
+ )
+ def test_reset_password_success(self, mocker, create_mock_response):
+ """Test case for reset_password with valid reset data"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_reset import AccountReset
+
+ reset_data = AccountReset(activation_code="reset-code-123", password="newpass123")
+ api.reset_password(account_reset=reset_data)
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "invalid reset code"}, "status": 400}],
+ indirect=True,
+ )
+ def test_reset_password_invalid_code(self, mocker, create_mock_response):
+ """Test case for reset_password with invalid reset code"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_reset import AccountReset
+
+ reset_data = AccountReset(activation_code="invalid-code", password="newpass")
+ with pytest.raises((ServiceException, Exception)):
+ api.reset_password(account_reset=reset_data)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 200}],
+ indirect=True,
+ )
+ def test_reset_password_with_http_info(self, mocker, create_mock_response):
+ """Test case for reset_password_with_http_info"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ from ibutsu_client.models.account_reset import AccountReset
+
+ reset_data = AccountReset(activation_code="code", password="newpass")
+ result = api.reset_password_with_http_info(account_reset=reset_data)
+ assert result.status_code == 200
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "user": True,
+ "keycloak": True,
+ "google": False,
+ "github": False,
+ "facebook": False,
+ "gitlab": False,
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_support_success(self, mocker, create_mock_response):
+ """Test case for support - get support configuration"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.support()
+ assert isinstance(result, LoginSupport)
+ assert result.user is True
+ assert result.keycloak is True
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"user": True, "google": True}, "status": 200}],
+ indirect=True,
+ )
+ def test_support_with_http_info(self, mocker, create_mock_response):
+ """Test case for support_with_http_info"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.support_with_http_info()
+ assert result.status_code == 200
+ assert isinstance(result.data, LoginSupport)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "internal error"}, "status": 500}],
+ indirect=True,
+ )
+ def test_support_server_error(self, mocker, create_mock_response):
+ """Test case for support with server error"""
+ api = LoginApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ with pytest.raises(ServiceException):
+ api.support()
diff --git a/test/test_project_api.py b/test/test_project_api.py
index 971ec31..9d05c4f 100644
--- a/test/test_project_api.py
+++ b/test/test_project_api.py
@@ -3,6 +3,8 @@
from urllib.parse import parse_qs, urlparse
from uuid import uuid4
+import pytest
+
from ibutsu_client.api.project_api import ProjectApi
from ibutsu_client.models.project import Project
from ibutsu_client.models.project_list import ProjectList
@@ -11,19 +13,30 @@
class TestProjectApi:
"""ProjectApi Tests"""
- def test_add_project(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "PROJECT_ID_PLACEHOLDER",
+ "name": "test-project",
+ "title": "Test Project",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_project(self, mock_api_client, create_mock_response):
"""Test case for add_project"""
api = ProjectApi(api_client=mock_api_client)
project_id = uuid4()
- project_data = {
- "id": str(project_id),
- "name": "test-project",
- "title": "Test Project",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=project_data, status=201)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual project_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"PROJECT_ID_PLACEHOLDER", str(project_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Create project object to send
project_item = Project(name="test-project", title="Test Project")
@@ -47,18 +60,29 @@ def test_add_project(self, mock_api_client, mock_rest_response):
assert args[3]["name"] == "test-project"
assert args[3]["title"] == "Test Project"
- def test_get_project(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "PROJECT_ID_PLACEHOLDER",
+ "name": "test-project",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_project(self, mock_api_client, create_mock_response):
"""Test case for get_project"""
api = ProjectApi(api_client=mock_api_client)
project_id = uuid4()
- project_data = {
- "id": str(project_id),
- "name": "test-project",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=project_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual project_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"PROJECT_ID_PLACEHOLDER", str(project_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_project(id=str(project_id))
@@ -74,21 +98,28 @@ def test_get_project(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/project/{project_id}")
- def test_get_project_list(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "projects": [
+ {"id": "00000000-0000-0000-0000-000000000001", "name": "project1"},
+ {"id": "00000000-0000-0000-0000-000000000002", "name": "project2"},
+ ],
+ "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_project_list(self, mock_api_client, create_mock_response):
"""Test case for get_project_list"""
api = ProjectApi(api_client=mock_api_client)
- project_list_data = {
- "projects": [
- {"id": str(uuid4()), "name": "project1"},
- {"id": str(uuid4()), "name": "project2"},
- ],
- "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
- }
-
# Mock the API response
- mock_response = mock_rest_response(data=project_list_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_project_list(page=1, page_size=25, owner_id="user1")
@@ -112,18 +143,29 @@ def test_get_project_list(self, mock_api_client, mock_rest_response):
assert query_params["pageSize"] == ["25"]
assert query_params["ownerId"] == ["user1"]
- def test_update_project(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "PROJECT_ID_PLACEHOLDER",
+ "name": "updated-project",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_update_project(self, mock_api_client, create_mock_response):
"""Test case for update_project"""
api = ProjectApi(api_client=mock_api_client)
project_id = uuid4()
- project_data = {
- "id": str(project_id),
- "name": "updated-project",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=project_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual project_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"PROJECT_ID_PLACEHOLDER", str(project_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Update object
project_update = Project(name="updated-project")
@@ -146,22 +188,30 @@ def test_update_project(self, mock_api_client, mock_rest_response):
assert isinstance(args[3], dict)
assert args[3]["name"] == "updated-project"
- def test_get_filter_params(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": ["env", "component", "tag"],
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_filter_params(self, mock_api_client, create_mock_response):
"""Test case for get_filter_params"""
api = ProjectApi(api_client=mock_api_client)
project_id = uuid4()
- filter_params = ["env", "component", "tag"]
# Mock the API response
- mock_response = mock_rest_response(data=filter_params, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call API
response = api.get_filter_params(id=str(project_id))
# Verify result
assert isinstance(response, list)
- assert response == filter_params
+ assert response == ["env", "component", "tag"]
# Verify call
mock_api_client.call_api.assert_called_once()
diff --git a/test/test_result_api.py b/test/test_result_api.py
index a122d12..0593c49 100644
--- a/test/test_result_api.py
+++ b/test/test_result_api.py
@@ -3,6 +3,8 @@
from urllib.parse import parse_qs, urlparse
from uuid import uuid4
+import pytest
+
from ibutsu_client.api.result_api import ResultApi
from ibutsu_client.models.result import Result
from ibutsu_client.models.result_list import ResultList
@@ -11,20 +13,31 @@
class TestResultApi:
"""ResultApi Tests"""
- def test_add_result(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "RESULT_ID_PLACEHOLDER",
+ "test_id": "test_case_1",
+ "result": "passed",
+ "duration": 1.5,
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_result(self, mock_api_client, create_mock_response):
"""Test case for add_result"""
api = ResultApi(api_client=mock_api_client)
result_id = uuid4()
- result_data = {
- "id": str(result_id),
- "test_id": "test_case_1",
- "result": "passed",
- "duration": 1.5,
- }
- # Mock the API response
- mock_response = mock_rest_response(data=result_data, status=201)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual result_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"RESULT_ID_PLACEHOLDER", str(result_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Create result object to send
result_item = Result(test_id="test_case_1", result="passed", duration=1.5)
@@ -50,19 +63,30 @@ def test_add_result(self, mock_api_client, mock_rest_response):
assert args[3]["result"] == "passed"
assert args[3]["duration"] == 1.5
- def test_get_result(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "RESULT_ID_PLACEHOLDER",
+ "test_id": "test_case_1",
+ "result": "passed",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_result(self, mock_api_client, create_mock_response):
"""Test case for get_result"""
api = ResultApi(api_client=mock_api_client)
result_id = uuid4()
- result_data = {
- "id": str(result_id),
- "test_id": "test_case_1",
- "result": "passed",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=result_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual result_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"RESULT_ID_PLACEHOLDER", str(result_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_result(id=result_id)
@@ -78,21 +102,36 @@ def test_get_result(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/result/{result_id}")
- def test_get_result_list(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "results": [
+ {
+ "id": "00000000-0000-0000-0000-000000000001",
+ "test_id": "test_1",
+ "result": "passed",
+ },
+ {
+ "id": "00000000-0000-0000-0000-000000000002",
+ "test_id": "test_2",
+ "result": "failed",
+ },
+ ],
+ "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_result_list(self, mock_api_client, create_mock_response):
"""Test case for get_result_list"""
api = ResultApi(api_client=mock_api_client)
- result_list_data = {
- "results": [
- {"id": str(uuid4()), "test_id": "test_1", "result": "passed"},
- {"id": str(uuid4()), "test_id": "test_2", "result": "failed"},
- ],
- "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
- }
-
# Mock the API response
- mock_response = mock_rest_response(data=result_list_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_result_list(page=1, page_size=25, filter=["result=passed"])
@@ -116,19 +155,30 @@ def test_get_result_list(self, mock_api_client, mock_rest_response):
assert query_params["pageSize"] == ["25"]
assert query_params["filter"] == ["result=passed"]
- def test_update_result(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "RESULT_ID_PLACEHOLDER",
+ "test_id": "test_case_1",
+ "result": "failed",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_update_result(self, mock_api_client, create_mock_response):
"""Test case for update_result"""
api = ResultApi(api_client=mock_api_client)
result_id = uuid4()
- result_data = {
- "id": str(result_id),
- "test_id": "test_case_1",
- "result": "failed", # Updated result
- }
- # Mock the API response
- mock_response = mock_rest_response(data=result_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual result_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"RESULT_ID_PLACEHOLDER", str(result_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Update object
result_update = Result(result="failed")
diff --git a/test/test_run_api.py b/test/test_run_api.py
index 22ace4e..0ecde65 100644
--- a/test/test_run_api.py
+++ b/test/test_run_api.py
@@ -3,6 +3,8 @@
from urllib.parse import parse_qs, urlparse
from uuid import uuid4
+import pytest
+
from ibutsu_client.api.run_api import RunApi
from ibutsu_client.models.run import Run
from ibutsu_client.models.run_list import RunList
@@ -12,19 +14,30 @@
class TestRunApi:
"""RunApi Tests"""
- def test_add_run(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "RUN_ID_PLACEHOLDER",
+ "component": "test-component",
+ "env": "ci",
+ },
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_run(self, mock_api_client, create_mock_response):
"""Test case for add_run"""
api = RunApi(api_client=mock_api_client)
run_id = uuid4()
- run_data = {
- "id": str(run_id),
- "component": "test-component",
- "env": "ci",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=run_data, status=201)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual run_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"RUN_ID_PLACEHOLDER", str(run_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Create run object to send
run_item = Run(component="test-component", env="ci")
@@ -48,18 +61,29 @@ def test_add_run(self, mock_api_client, mock_rest_response):
assert args[3]["component"] == "test-component"
assert args[3]["env"] == "ci"
- def test_get_run(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "RUN_ID_PLACEHOLDER",
+ "component": "test-component",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_run(self, mock_api_client, create_mock_response):
"""Test case for get_run"""
api = RunApi(api_client=mock_api_client)
run_id = uuid4()
- run_data = {
- "id": str(run_id),
- "component": "test-component",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=run_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual run_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"RUN_ID_PLACEHOLDER", str(run_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_run(id=run_id)
@@ -75,21 +99,28 @@ def test_get_run(self, mock_api_client, mock_rest_response):
assert args[0] == "GET"
assert args[1].endswith(f"/run/{run_id}")
- def test_get_run_list(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "runs": [
+ {"id": "00000000-0000-0000-0000-000000000001", "component": "comp1"},
+ {"id": "00000000-0000-0000-0000-000000000002", "component": "comp2"},
+ ],
+ "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_run_list(self, mock_api_client, create_mock_response):
"""Test case for get_run_list"""
api = RunApi(api_client=mock_api_client)
- run_list_data = {
- "runs": [
- {"id": str(uuid4()), "component": "comp1"},
- {"id": str(uuid4()), "component": "comp2"},
- ],
- "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
- }
-
# Mock the API response
- mock_response = mock_rest_response(data=run_list_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Call the API
response = api.get_run_list(page=1, page_size=25, filter=["env=ci"])
@@ -113,18 +144,29 @@ def test_get_run_list(self, mock_api_client, mock_rest_response):
assert query_params["pageSize"] == ["25"]
assert query_params["filter"] == ["env=ci"]
- def test_update_run(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "RUN_ID_PLACEHOLDER",
+ "component": "updated-component",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_update_run(self, mock_api_client, create_mock_response):
"""Test case for update_run"""
api = RunApi(api_client=mock_api_client)
run_id = uuid4()
- run_data = {
- "id": str(run_id),
- "component": "updated-component",
- }
- # Mock the API response
- mock_response = mock_rest_response(data=run_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ # Update the mock response with the actual run_id
+ create_mock_response.data = create_mock_response.data.replace(
+ b"RUN_ID_PLACEHOLDER", str(run_id).encode()
+ )
+ mock_api_client.call_api.return_value = create_mock_response
# Update object
run_update = Run(component="updated-component")
@@ -147,21 +189,36 @@ def test_update_run(self, mock_api_client, mock_rest_response):
assert isinstance(args[3], dict)
assert args[3]["component"] == "updated-component"
- def test_bulk_update(self, mock_api_client, mock_rest_response):
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "runs": [
+ {
+ "id": "00000000-0000-0000-0000-000000000001",
+ "component": "comp1",
+ "metadata": {"new": "val"},
+ },
+ {
+ "id": "00000000-0000-0000-0000-000000000002",
+ "component": "comp2",
+ "metadata": {"new": "val"},
+ },
+ ],
+ "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_bulk_update(self, mock_api_client, create_mock_response):
"""Test case for bulk_update"""
api = RunApi(api_client=mock_api_client)
- run_list_data = {
- "runs": [
- {"id": str(uuid4()), "component": "comp1", "metadata": {"new": "val"}},
- {"id": str(uuid4()), "component": "comp2", "metadata": {"new": "val"}},
- ],
- "pagination": {"page": 1, "pageSize": 25, "totalItems": 2, "totalPages": 1},
- }
-
# Mock the API response
- mock_response = mock_rest_response(data=run_list_data, status=200)
- mock_api_client.call_api.return_value = mock_response
+ mock_api_client.call_api.return_value = create_mock_response
# Update object
update_data = UpdateRun(metadata={"new": "val"})
diff --git a/test/test_task_api.py b/test/test_task_api.py
index 31d589f..558c837 100644
--- a/test/test_task_api.py
+++ b/test/test_task_api.py
@@ -9,26 +9,245 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.task_api import TaskApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
-class TestTaskApi(unittest.TestCase):
- """TaskApi unit test stubs"""
+class TestTaskApi:
+ """TaskApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = TaskApi()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "status": "pending",
+ "task_type": "export",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_task_pending(self, mocker, create_mock_response):
+ """Test case for get_task with pending status"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def tearDown(self) -> None:
- pass
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_task(id=task_id)
- def test_get_task(self) -> None:
- """Test case for get_task
+ assert result is not None
+ assert result["status"] == "pending"
+ assert result["task_type"] == "export"
+ api.api_client.call_api.assert_called_once()
- Get the status or result of a task
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "status": "running",
+ "task_type": "bulk_update",
+ "progress": 45,
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_task_running(self, mocker, create_mock_response):
+ """Test case for get_task with running status"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_task(id=task_id)
-if __name__ == "__main__":
- unittest.main()
+ assert result is not None
+ assert result["status"] == "running"
+ assert result["progress"] == 45
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "status": "completed",
+ "task_type": "export",
+ "result": {
+ "file_url": "https://example.com/exports/results.tar.gz",
+ "file_size": 1024000,
+ },
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_task_completed(self, mocker, create_mock_response):
+ """Test case for get_task with completed status"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_task(id=task_id)
+
+ assert result is not None
+ assert result["status"] == "completed"
+ assert result["result"]["file_url"] == "https://example.com/exports/results.tar.gz"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "status": "failed",
+ "task_type": "bulk_update",
+ "error": "Database connection timeout",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_task_failed(self, mocker, create_mock_response):
+ """Test case for get_task with failed status"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_task(id=task_id)
+
+ assert result is not None
+ assert result["status"] == "failed"
+ assert result["error"] == "Database connection timeout"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "task not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_get_task_not_found(self, mocker, create_mock_response):
+ """Test case for get_task with non-existent task"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.get_task(id=task_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "status": "completed",
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_task_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_task_with_http_info"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_task_with_http_info(id=task_id)
+
+ assert result.status_code == 200
+ assert result.data is not None
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 401}],
+ indirect=True,
+ )
+ def test_get_task_unauthorized(self, mocker, create_mock_response):
+ """Test case for get_task without authentication"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises((ServiceException, Exception)):
+ api.get_task(id=task_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "internal error"}, "status": 500}],
+ indirect=True,
+ )
+ def test_get_task_server_error(self, mocker, create_mock_response):
+ """Test case for get_task with server error"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(ServiceException):
+ api.get_task(id=task_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "status": "completed",
+ "task_type": "export",
+ "result": {
+ "format": "json",
+ "records_exported": 1000,
+ },
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_task_export_type(self, mocker, create_mock_response):
+ """Test case for get_task with export task type"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_task(id=task_id)
+
+ assert result["task_type"] == "export"
+ assert result["result"]["records_exported"] == 1000
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "id": "550e8400-e29b-41d4-a716-446655440000",
+ "status": "completed",
+ "task_type": "bulk_update",
+ "result": {
+ "updated_count": 150,
+ },
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_task_bulk_update_type(self, mocker, create_mock_response):
+ """Test case for get_task with bulk_update task type"""
+ api = TaskApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ task_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_task(id=task_id)
+
+ assert result["task_type"] == "bulk_update"
+ assert result["result"]["updated_count"] == 150
diff --git a/test/test_user_api.py b/test/test_user_api.py
index d43a303..5207938 100644
--- a/test/test_user_api.py
+++ b/test/test_user_api.py
@@ -9,56 +9,338 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.user_api import UserApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
+from ibutsu_client.models.create_token import CreateToken
+from ibutsu_client.models.token import Token
+from ibutsu_client.models.token_list import TokenList
+from ibutsu_client.models.user import User
+from test.utils import sample_pagination_data, sample_token_data, sample_user_data
-class TestUserApi(unittest.TestCase):
- """UserApi unit test stubs"""
+class TestUserApi:
+ """UserApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = UserApi()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_token_data(name="api-token", expires="2025-12-31"), "status": 201}],
+ indirect=True,
+ )
+ def test_add_token_success(self, mocker, create_mock_response):
+ """Test case for add_token - successfully create a token"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def tearDown(self) -> None:
- pass
+ create_token = CreateToken(name="api-token", expires="2025-12-31")
+ result = api.add_token(create_token=create_token)
- def test_add_token(self) -> None:
- """Test case for add_token
+ assert isinstance(result, Token)
+ assert result.name == "api-token"
+ assert result.expires == "2025-12-31"
+ api.api_client.call_api.assert_called_once()
- Create a token for the current user
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 401}],
+ indirect=True,
+ )
+ def test_add_token_unauthorized(self, mocker, create_mock_response):
+ """Test case for add_token with no authentication"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_delete_token(self) -> None:
- """Test case for delete_token
+ create_token = CreateToken(name="test-token", expires="2025-12-31")
+ with pytest.raises((ServiceException, Exception)): # Should raise unauthorized exception
+ api.add_token(create_token=create_token)
- Delete the token
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_token_data(name="test-token"), "status": 201}],
+ indirect=True,
+ )
+ def test_add_token_with_http_info(self, mocker, create_mock_response):
+ """Test case for add_token_with_http_info"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_get_current_user(self) -> None:
- """Test case for get_current_user
+ create_token = CreateToken(name="test-token", expires="2025-12-31")
+ result = api.add_token_with_http_info(create_token=create_token)
- Return the user details for the current user
- """
+ assert result.status_code == 201
+ assert isinstance(result.data, Token)
- def test_get_token(self) -> None:
- """Test case for get_token
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 204}],
+ indirect=True,
+ )
+ def test_delete_token_success(self, mocker, create_mock_response):
+ """Test case for delete_token - successfully delete a token"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- Retrieve a single token for the current user
- """
+ token_id = "550e8400-e29b-41d4-a716-446655440000"
+ api.delete_token(id=token_id)
- def test_get_token_list(self) -> None:
- """Test case for get_token_list
+ # 204 No Content typically returns None
+ api.api_client.call_api.assert_called_once()
- Return the tokens for the user
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_delete_token_not_found(self, mocker, create_mock_response):
+ """Test case for delete_token with non-existent token"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_update_current_user(self) -> None:
- """Test case for update_current_user
+ token_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.delete_token(id=token_id)
- Return the user details for the current user
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 204}],
+ indirect=True,
+ )
+ def test_delete_token_with_http_info(self, mocker, create_mock_response):
+ """Test case for delete_token_with_http_info"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+ token_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.delete_token_with_http_info(id=token_id)
-if __name__ == "__main__":
- unittest.main()
+ assert result.status_code == 204
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_user_data(email="current@example.com", name="Current User"),
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_current_user_success(self, mocker, create_mock_response):
+ """Test case for get_current_user - retrieve current user details"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_current_user()
+
+ assert isinstance(result, User)
+ assert result.email == "current@example.com"
+ assert result.name == "Current User"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 401}],
+ indirect=True,
+ )
+ def test_get_current_user_unauthorized(self, mocker, create_mock_response):
+ """Test case for get_current_user without authentication"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ with pytest.raises((ServiceException, Exception)):
+ api.get_current_user()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_user_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_get_current_user_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_current_user_with_http_info"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_current_user_with_http_info()
+
+ assert result.status_code == 200
+ assert isinstance(result.data, User)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_token_data(name="specific-token"), "status": 200}],
+ indirect=True,
+ )
+ def test_get_token_success(self, mocker, create_mock_response):
+ """Test case for get_token - retrieve a single token"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ token_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_token(id=token_id)
+
+ assert isinstance(result, Token)
+ assert result.name == "specific-token"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_get_token_not_found(self, mocker, create_mock_response):
+ """Test case for get_token with non-existent token"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ token_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.get_token(id=token_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_token_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_get_token_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_token_with_http_info"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ token_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_token_with_http_info(id=token_id)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, Token)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "tokens": [
+ sample_token_data(name="token1"),
+ sample_token_data(name="token2"),
+ ],
+ "pagination": sample_pagination_data(page=1, page_size=25, total_items=2),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_token_list_success(self, mocker, create_mock_response):
+ """Test case for get_token_list - retrieve list of tokens"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_token_list()
+
+ assert isinstance(result, TokenList)
+ assert len(result.tokens) == 2
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "tokens": [sample_token_data()],
+ "pagination": sample_pagination_data(page=2, page_size=10),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_token_list_with_pagination(self, mocker, create_mock_response):
+ """Test case for get_token_list with pagination parameters"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_token_list(page=2, page_size=10)
+
+ assert isinstance(result, TokenList)
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "tokens": [],
+ "pagination": sample_pagination_data(),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_token_list_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_token_list_with_http_info"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_token_list_with_http_info()
+
+ assert result.status_code == 200
+ assert isinstance(result.data, TokenList)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_user_data(email="current@example.com", name="Current User"),
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_update_current_user_success(self, mocker, create_mock_response):
+ """Test case for update_current_user - get current user details"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.update_current_user()
+
+ assert isinstance(result, User)
+ assert result.email == "current@example.com"
+ assert result.name == "Current User"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 401}],
+ indirect=True,
+ )
+ def test_update_current_user_unauthorized(self, mocker, create_mock_response):
+ """Test case for update_current_user without authentication"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ with pytest.raises((ServiceException, Exception)):
+ api.update_current_user()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_user_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_update_current_user_with_http_info(self, mocker, create_mock_response):
+ """Test case for update_current_user_with_http_info"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.update_current_user_with_http_info()
+
+ assert result.status_code == 200
+ assert isinstance(result.data, User)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "internal error"}, "status": 500}],
+ indirect=True,
+ )
+ def test_update_current_user_server_error(self, mocker, create_mock_response):
+ """Test case for update_current_user with server error"""
+ api = UserApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ with pytest.raises(ServiceException):
+ api.update_current_user()
diff --git a/test/test_widget_api.py b/test/test_widget_api.py
index 345f8cb..7fb7145 100644
--- a/test/test_widget_api.py
+++ b/test/test_widget_api.py
@@ -9,32 +9,198 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.widget_api import WidgetApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
+from ibutsu_client.models.widget_type_list import WidgetTypeList
-class TestWidgetApi(unittest.TestCase):
- """WidgetApi unit test stubs"""
+class TestWidgetApi:
+ """WidgetApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = WidgetApi()
+ # Parametrized tests for get_widget with various scenarios
+ @pytest.mark.parametrize(
+ "create_mock_response,widget_params,expected_type,expected_exception",
+ [
+ pytest.param(
+ {
+ "data": {
+ "type": "result-summary",
+ "data": {"passed": 100, "failed": 5, "skipped": 2, "error": 0},
+ },
+ "status": 200,
+ },
+ {},
+ "result-summary",
+ None,
+ id="success_basic",
+ ),
+ pytest.param(
+ {
+ "data": {"type": "jenkins-heatmap", "data": {"rows": [], "columns": []}},
+ "status": 200,
+ },
+ {"params": {"project": "test-project", "env": "production"}},
+ "jenkins-heatmap",
+ None,
+ id="success_with_filters",
+ ),
+ pytest.param(
+ {
+ "data": {"type": "result-aggregation", "data": {"aggregations": []}},
+ "status": 200,
+ },
+ {"params": {"group_by": "component", "limit": 10}},
+ "result-aggregation",
+ None,
+ id="success_with_params",
+ ),
+ pytest.param(
+ {"data": {"error": "widget not found"}, "status": 404},
+ {},
+ None,
+ NotFoundException,
+ id="not_found",
+ ),
+ pytest.param(
+ {"data": {"error": "internal error"}, "status": 500},
+ {},
+ None,
+ ServiceException,
+ id="server_error",
+ ),
+ ],
+ indirect=["create_mock_response"],
+ )
+ def test_get_widget(
+ self, mocker, create_mock_response, widget_params, expected_type, expected_exception
+ ):
+ """Test get_widget with various response scenarios."""
+ api = WidgetApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def tearDown(self) -> None:
- pass
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
- def test_get_widget(self) -> None:
- """Test case for get_widget
+ if expected_exception:
+ with pytest.raises(expected_exception):
+ api.get_widget(id=widget_id, **widget_params)
+ else:
+ result = api.get_widget(id=widget_id, **widget_params)
+ assert result is not None
+ assert result["type"] == expected_type
+ api.api_client.call_api.assert_called_once()
- Generate data for a dashboard widget
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ pytest.param(
+ {"data": {"type": "test-widget", "data": {}}, "status": 200},
+ id="http_info_success",
+ ),
+ ],
+ indirect=True,
+ )
+ def test_get_widget_with_http_info(self, mocker, create_mock_response):
+ """Test get_widget_with_http_info."""
+ api = WidgetApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_get_widget_types(self) -> None:
- """Test case for get_widget_types
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_widget_with_http_info(id=widget_id)
- Get a list of widget types
- """
+ assert result.status_code == 200
+ assert result.data is not None
+ # Parametrized tests for get_widget_types
+ @pytest.mark.parametrize(
+ "create_mock_response,expected_count,expected_exception",
+ [
+ pytest.param(
+ {
+ "data": {
+ "types": [
+ {
+ "name": "result-summary",
+ "description": "Summary of test results",
+ "params": [],
+ },
+ {
+ "name": "jenkins-heatmap",
+ "description": "Jenkins build heatmap",
+ "params": [],
+ },
+ {
+ "name": "result-aggregation",
+ "description": "Aggregated test results",
+ "params": [],
+ },
+ ]
+ },
+ "status": 200,
+ },
+ 3,
+ None,
+ id="success_multiple_types",
+ ),
+ pytest.param(
+ {"data": {"types": []}, "status": 200},
+ 0,
+ None,
+ id="success_empty",
+ ),
+ pytest.param(
+ {"data": {"error": "internal error"}, "status": 500},
+ None,
+ ServiceException,
+ id="server_error",
+ ),
+ ],
+ indirect=["create_mock_response"],
+ )
+ def test_get_widget_types(
+ self, mocker, create_mock_response, expected_count, expected_exception
+ ):
+ """Test get_widget_types with various response scenarios."""
+ api = WidgetApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
-if __name__ == "__main__":
- unittest.main()
+ if expected_exception:
+ with pytest.raises(expected_exception):
+ api.get_widget_types()
+ else:
+ result = api.get_widget_types()
+ assert isinstance(result, WidgetTypeList)
+ assert len(result.types) == expected_count
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ pytest.param(
+ {
+ "data": {
+ "types": [
+ {
+ "name": "result-summary",
+ "description": "Summary",
+ "params": [],
+ }
+ ]
+ },
+ "status": 200,
+ },
+ id="http_info_success",
+ ),
+ ],
+ indirect=True,
+ )
+ def test_get_widget_types_with_http_info(self, mocker, create_mock_response):
+ """Test get_widget_types_with_http_info."""
+ api = WidgetApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_widget_types_with_http_info()
+
+ assert result.status_code == 200
+ assert isinstance(result.data, WidgetTypeList)
diff --git a/test/test_widget_config_api.py b/test/test_widget_config_api.py
index 486e106..e568c52 100644
--- a/test/test_widget_config_api.py
+++ b/test/test_widget_config_api.py
@@ -9,50 +9,355 @@
Do not edit the class manually.
"""
-import unittest
+import pytest
from ibutsu_client.api.widget_config_api import WidgetConfigApi
+from ibutsu_client.exceptions import NotFoundException, ServiceException
+from ibutsu_client.models.widget_config import WidgetConfig
+from ibutsu_client.models.widget_config_list import WidgetConfigList
+from test.utils import sample_pagination_data, sample_widget_config_data
-class TestWidgetConfigApi(unittest.TestCase):
- """WidgetConfigApi unit test stubs"""
+class TestWidgetConfigApi:
+ """WidgetConfigApi comprehensive tests"""
- def setUp(self) -> None:
- self.api = WidgetConfigApi()
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_widget_config_data(widget="result-summary", weight=0),
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_widget_config_success(self, mocker, create_mock_response):
+ """Test case for add_widget_config - successfully create a widget config"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def tearDown(self) -> None:
- pass
+ widget_config = WidgetConfig(type="widget", widget="result-summary", weight=0, params={})
+ result = api.add_widget_config(widget_config=widget_config)
- def test_add_widget_config(self) -> None:
- """Test case for add_widget_config
+ assert isinstance(result, WidgetConfig)
+ assert result.widget == "result-summary"
+ assert result.weight == 0
+ api.api_client.call_api.assert_called_once()
- Create a widget configuration
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_widget_config_data(
+ widget="result-aggregation",
+ weight=5,
+ params={"filter": "result:passed", "chart_type": "bar"},
+ ),
+ "status": 201,
+ }
+ ],
+ indirect=True,
+ )
+ def test_add_widget_config_with_params(self, mocker, create_mock_response):
+ """Test case for add_widget_config with widget parameters"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- def test_delete_widget_config(self) -> None:
- """Test case for delete_widget_config
+ params = {"filter": "result:passed", "chart_type": "bar"}
+ widget_config = WidgetConfig(
+ type="widget", widget="result-aggregation", weight=5, params=params
+ )
+ result = api.add_widget_config(widget_config=widget_config)
- Delete a widget configuration
- """
+ assert isinstance(result, WidgetConfig)
+ assert result.params == params
- def test_get_widget_config(self) -> None:
- """Test case for get_widget_config
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "unauthorized"}, "status": 401}],
+ indirect=True,
+ )
+ def test_add_widget_config_unauthorized(self, mocker, create_mock_response):
+ """Test case for add_widget_config without authentication"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- Get a single widget configuration
- """
+ widget_config = WidgetConfig(type="widget", widget="test", weight=0)
+ with pytest.raises((ServiceException, Exception)):
+ api.add_widget_config(widget_config=widget_config)
- def test_get_widget_config_list(self) -> None:
- """Test case for get_widget_config_list
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_widget_config_data(), "status": 201}],
+ indirect=True,
+ )
+ def test_add_widget_config_with_http_info(self, mocker, create_mock_response):
+ """Test case for add_widget_config_with_http_info"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
- Get the list of widget configurations
- """
+ widget_config = WidgetConfig(type="widget", widget="test", weight=0)
+ result = api.add_widget_config_with_http_info(widget_config=widget_config)
- def test_update_widget_config(self) -> None:
- """Test case for update_widget_config
+ assert result.status_code == 201
+ assert isinstance(result.data, WidgetConfig)
- Updates a single widget configuration
- """
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 204}],
+ indirect=True,
+ )
+ def test_delete_widget_config_success(self, mocker, create_mock_response):
+ """Test case for delete_widget_config - successfully delete a widget"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ api.delete_widget_config(id=widget_id)
-if __name__ == "__main__":
- unittest.main()
+ # 204 No Content typically returns None
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_delete_widget_config_not_found(self, mocker, create_mock_response):
+ """Test case for delete_widget_config with non-existent widget"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.delete_widget_config(id=widget_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {}, "status": 204}],
+ indirect=True,
+ )
+ def test_delete_widget_config_with_http_info(self, mocker, create_mock_response):
+ """Test case for delete_widget_config_with_http_info"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.delete_widget_config_with_http_info(id=widget_id)
+
+ assert result.status_code == 204
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_widget_config_data(widget="jenkins-heatmap"),
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_widget_config_success(self, mocker, create_mock_response):
+ """Test case for get_widget_config - retrieve a single widget config"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_widget_config(id=widget_id)
+
+ assert isinstance(result, WidgetConfig)
+ assert result.widget == "jenkins-heatmap"
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_get_widget_config_not_found(self, mocker, create_mock_response):
+ """Test case for get_widget_config with non-existent widget"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ with pytest.raises(NotFoundException):
+ api.get_widget_config(id=widget_id)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_widget_config_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_get_widget_config_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_widget_config_with_http_info"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ result = api.get_widget_config_with_http_info(id=widget_id)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, WidgetConfig)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "widgets": [
+ sample_widget_config_data(widget="result-summary", weight=0),
+ sample_widget_config_data(widget="jenkins-heatmap", weight=1),
+ ],
+ "pagination": sample_pagination_data(total_items=2),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_widget_config_list_success(self, mocker, create_mock_response):
+ """Test case for get_widget_config_list - retrieve list of widget configs"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_widget_config_list()
+
+ assert isinstance(result, WidgetConfigList)
+ assert len(result.widgets) == 2
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "widgets": [sample_widget_config_data()],
+ "pagination": sample_pagination_data(total_items=1),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_widget_config_list_with_filters(self, mocker, create_mock_response):
+ """Test case for get_widget_config_list with filter parameters"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_widget_config_list(filter=["widget_type=result-summary"])
+
+ assert isinstance(result, WidgetConfigList)
+ api.api_client.call_api.assert_called_once()
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "widgets": [],
+ "pagination": sample_pagination_data(total_items=0),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_widget_config_list_empty(self, mocker, create_mock_response):
+ """Test case for get_widget_config_list with no widgets"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_widget_config_list()
+
+ assert isinstance(result, WidgetConfigList)
+ assert len(result.widgets) == 0
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": {
+ "widgets": [],
+ "pagination": sample_pagination_data(),
+ },
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_get_widget_config_list_with_http_info(self, mocker, create_mock_response):
+ """Test case for get_widget_config_list_with_http_info"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ result = api.get_widget_config_list_with_http_info()
+
+ assert result.status_code == 200
+ assert isinstance(result.data, WidgetConfigList)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [
+ {
+ "data": sample_widget_config_data(widget="result-summary", weight=10),
+ "status": 200,
+ }
+ ],
+ indirect=True,
+ )
+ def test_update_widget_config_success(self, mocker, create_mock_response):
+ """Test case for update_widget_config - successfully update a widget config"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ widget_config = WidgetConfig(type="widget", widget="result-summary", weight=10)
+ result = api.update_widget_config(id=widget_id, widget_config=widget_config)
+
+ assert isinstance(result, WidgetConfig)
+ assert result.weight == 10
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "not found"}, "status": 404}],
+ indirect=True,
+ )
+ def test_update_widget_config_not_found(self, mocker, create_mock_response):
+ """Test case for update_widget_config with non-existent widget"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ widget_config = WidgetConfig(type="widget", widget="test", weight=0)
+ with pytest.raises(NotFoundException):
+ api.update_widget_config(id=widget_id, widget_config=widget_config)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": sample_widget_config_data(), "status": 200}],
+ indirect=True,
+ )
+ def test_update_widget_config_with_http_info(self, mocker, create_mock_response):
+ """Test case for update_widget_config_with_http_info"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ widget_config = WidgetConfig(type="widget", widget="test", weight=5)
+ result = api.update_widget_config_with_http_info(id=widget_id, widget_config=widget_config)
+
+ assert result.status_code == 200
+ assert isinstance(result.data, WidgetConfig)
+
+ @pytest.mark.parametrize(
+ "create_mock_response",
+ [{"data": {"error": "internal error"}, "status": 500}],
+ indirect=True,
+ )
+ def test_update_widget_config_server_error(self, mocker, create_mock_response):
+ """Test case for update_widget_config with server error"""
+ api = WidgetConfigApi()
+ mocker.patch.object(api.api_client, "call_api", return_value=create_mock_response)
+
+ widget_id = "550e8400-e29b-41d4-a716-446655440000"
+ widget_config = WidgetConfig(type="widget", widget="test", weight=0)
+ with pytest.raises(ServiceException):
+ api.update_widget_config(id=widget_id, widget_config=widget_config)
diff --git a/test/utils.py b/test/utils.py
new file mode 100644
index 0000000..f32e4f5
--- /dev/null
+++ b/test/utils.py
@@ -0,0 +1,372 @@
+"""Test data factory functions for ibutsu_client tests."""
+
+import uuid
+from typing import Any
+
+
+def sample_project_data(
+ project_id: str | None = None,
+ name: str = "test-project",
+ title: str = "Test Project",
+ owner_id: str | None = None,
+ group_id: str | None = None,
+) -> dict[str, Any]:
+ """Factory function to create sample project data.
+
+ Args:
+ project_id: Project UUID (generated if not provided)
+ name: Machine name of the project
+ title: Human-readable title
+ owner_id: Owner UUID
+ group_id: Group UUID
+
+ Returns:
+ Dictionary with project data
+ """
+ if project_id is None:
+ project_id = str(uuid.uuid4())
+ if owner_id is None:
+ owner_id = str(uuid.uuid4())
+ if group_id is None:
+ group_id = str(uuid.uuid4())
+
+ return {
+ "id": project_id,
+ "name": name,
+ "title": title,
+ "owner_id": owner_id,
+ "group_id": group_id,
+ }
+
+
+def sample_run_data(
+ run_id: str | None = None,
+ project_id: str | None = None,
+ created: str = "2024-01-15T10:00:00",
+ start_time: str = "2024-01-15T10:00:00",
+ duration: float = 120.5,
+ source: str = "pytest",
+ component: str = "api",
+ env: str = "test",
+ summary: dict[str, Any] | None = None,
+ metadata: dict[str, Any] | None = None,
+) -> dict[str, Any]:
+ """Factory function to create sample test run data.
+
+ Args:
+ run_id: Run UUID (generated if not provided)
+ project_id: Project UUID (generated if not provided)
+ created: ISO timestamp of creation
+ start_time: ISO timestamp of run start
+ duration: Duration in seconds
+ source: Source system identifier
+ component: Component under test
+ env: Test environment
+ summary: Summary statistics
+ metadata: Additional metadata
+
+ Returns:
+ Dictionary with run data
+ """
+ if run_id is None:
+ run_id = str(uuid.uuid4())
+ if project_id is None:
+ project_id = str(uuid.uuid4())
+ if summary is None:
+ summary = {"passed": 10, "failed": 2, "skipped": 1, "errors": 0, "xfailed": 0}
+ if metadata is None:
+ metadata = {"jenkins_build": "123", "branch": "main"}
+
+ return {
+ "id": run_id,
+ "project_id": project_id,
+ "created": created,
+ "start_time": start_time,
+ "duration": duration,
+ "source": source,
+ "component": component,
+ "env": env,
+ "summary": summary,
+ "metadata": metadata,
+ }
+
+
+def sample_result_data(
+ result_id: str | None = None,
+ run_id: str | None = None,
+ project_id: str | None = None,
+ test_id: str = "test_example.py::TestClass::test_method",
+ start_time: str = "2024-01-15T10:00:00",
+ duration: float = 1.5,
+ result: str = "passed",
+ component: str = "api",
+ env: str = "test",
+ source: str = "pytest",
+ metadata: dict[str, Any] | None = None,
+ params: dict[str, Any] | None = None,
+) -> dict[str, Any]:
+ """Factory function to create sample test result data.
+
+ Args:
+ result_id: Result UUID (generated if not provided)
+ run_id: Associated run UUID (generated if not provided)
+ project_id: Project UUID (generated if not provided)
+ test_id: Test identifier
+ start_time: ISO timestamp
+ duration: Duration in seconds
+ result: Test result status (passed, failed, error, skipped, etc.)
+ component: Component under test
+ env: Test environment
+ source: Source system identifier
+ metadata: Additional metadata
+ params: Test parameters
+
+ Returns:
+ Dictionary with result data
+ """
+ if result_id is None:
+ result_id = str(uuid.uuid4())
+ if run_id is None:
+ run_id = str(uuid.uuid4())
+ if project_id is None:
+ project_id = str(uuid.uuid4())
+ if metadata is None:
+ metadata = {"test_file": "test_example.py", "line_number": 42}
+ if params is None:
+ params = {}
+
+ return {
+ "id": result_id,
+ "run_id": run_id,
+ "project_id": project_id,
+ "test_id": test_id,
+ "start_time": start_time,
+ "duration": duration,
+ "result": result,
+ "component": component,
+ "env": env,
+ "source": source,
+ "metadata": metadata,
+ "params": params,
+ }
+
+
+def sample_artifact_data(
+ artifact_id: str | None = None,
+ filename: str = "test_log.txt",
+ result_id: str | None = None,
+ run_id: str | None = None,
+ project_id: str | None = None,
+) -> dict[str, Any]:
+ """Factory function to create sample artifact data.
+
+ Args:
+ artifact_id: Artifact UUID (generated if not provided)
+ filename: Artifact filename
+ result_id: Associated result UUID
+ run_id: Associated run UUID
+ project_id: Project UUID
+
+ Returns:
+ Dictionary with artifact data
+ """
+ if artifact_id is None:
+ artifact_id = str(uuid.uuid4())
+ if result_id is None:
+ result_id = str(uuid.uuid4())
+ if run_id is None:
+ run_id = str(uuid.uuid4())
+ if project_id is None:
+ project_id = str(uuid.uuid4())
+
+ return {
+ "id": artifact_id,
+ "filename": filename,
+ "result_id": result_id,
+ "run_id": run_id,
+ "project_id": project_id,
+ }
+
+
+def sample_pagination_data(
+ page: int = 1,
+ page_size: int = 25,
+ total_items: int = 100,
+ total_pages: int = 4,
+) -> dict[str, Any]:
+ """Factory function to create sample pagination data.
+
+ Args:
+ page: Current page number
+ page_size: Number of items per page
+ total_items: Total number of items
+ total_pages: Total number of pages
+
+ Returns:
+ Dictionary with pagination data
+ """
+ return {
+ "page": page,
+ "pageSize": page_size,
+ "totalItems": total_items,
+ "totalPages": total_pages,
+ }
+
+
+def sample_user_data(
+ user_id: str | None = None,
+ email: str = "test@example.com",
+ name: str = "Test User",
+ is_superadmin: bool = False,
+ is_active: bool = True,
+) -> dict[str, Any]:
+ """Factory function to create sample user data.
+
+ Args:
+ user_id: User UUID (generated if not provided)
+ email: User email address
+ name: User full name
+ is_superadmin: Whether user is a superadmin
+ is_active: Whether user account is active
+
+ Returns:
+ Dictionary with user data
+ """
+ if user_id is None:
+ user_id = str(uuid.uuid4())
+
+ return {
+ "id": user_id,
+ "email": email,
+ "name": name,
+ "is_superadmin": is_superadmin,
+ "is_active": is_active,
+ }
+
+
+def sample_dashboard_data(
+ dashboard_id: str | None = None,
+ title: str = "Test Dashboard",
+ project_id: str | None = None,
+ description: str | None = None,
+ filters: str | None = None,
+) -> dict[str, Any]:
+ """Factory function to create sample dashboard data.
+
+ Args:
+ dashboard_id: Dashboard UUID (generated if not provided)
+ title: Dashboard title
+ project_id: Project UUID (generated if not provided)
+ description: Dashboard description
+ filters: Dashboard filters
+
+ Returns:
+ Dictionary with dashboard data
+ """
+ if dashboard_id is None:
+ dashboard_id = str(uuid.uuid4())
+ if project_id is None:
+ project_id = str(uuid.uuid4())
+
+ data = {
+ "id": dashboard_id,
+ "title": title,
+ "project_id": project_id,
+ }
+ if description is not None:
+ data["description"] = description
+ if filters is not None:
+ data["filters"] = filters
+
+ return data
+
+
+def sample_widget_config_data(
+ widget_id: str | None = None,
+ widget: str = "result-summary",
+ config_type: str = "widget",
+ weight: int = 0,
+ params: dict[str, Any] | None = None,
+ title: str | None = None,
+) -> dict[str, Any]:
+ """Factory function to create sample widget configuration data.
+
+ Args:
+ widget_id: Widget UUID (generated if not provided)
+ widget: Widget name to render
+ config_type: Type of config ("widget" or "view")
+ weight: Widget display weight/order
+ params: Widget parameters
+ title: Widget title
+
+ Returns:
+ Dictionary with widget config data
+ """
+ if widget_id is None:
+ widget_id = str(uuid.uuid4())
+ if params is None:
+ params = {}
+
+ return {
+ "id": widget_id,
+ "type": config_type,
+ "widget": widget,
+ "weight": weight,
+ "params": params,
+ "title": title,
+ }
+
+
+def sample_group_data(
+ group_id: str | None = None,
+ name: str = "test-group",
+) -> dict[str, Any]:
+ """Factory function to create sample group data.
+
+ Args:
+ group_id: Group UUID (generated if not provided)
+ name: Group name
+
+ Returns:
+ Dictionary with group data
+ """
+ if group_id is None:
+ group_id = str(uuid.uuid4())
+
+ return {
+ "id": group_id,
+ "name": name,
+ }
+
+
+def sample_token_data(
+ token_id: str | None = None,
+ user_id: str | None = None,
+ name: str = "test-token",
+ token: str = "test-token-value",
+ expires: str | None = "2025-12-31",
+) -> dict[str, Any]:
+ """Factory function to create sample token data.
+
+ Args:
+ token_id: Token UUID (generated if not provided)
+ user_id: User UUID (generated if not provided)
+ name: Token name/identifier
+ token: The actual token string
+ expires: Expiration date
+
+ Returns:
+ Dictionary with token data
+ """
+ if token_id is None:
+ token_id = str(uuid.uuid4())
+ if user_id is None:
+ user_id = str(uuid.uuid4())
+
+ return {
+ "id": token_id,
+ "user_id": user_id,
+ "name": name,
+ "token": token,
+ "expires": expires,
+ }