-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_abstract_operations.py
More file actions
110 lines (83 loc) · 3.47 KB
/
Copy pathtest_abstract_operations.py
File metadata and controls
110 lines (83 loc) · 3.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""Tests for abstract operations base classes."""
import pytest
from bloomy.utils.abstract_operations import AbstractOperations
class MockHTTPClient:
"""Mock HTTP client for testing."""
def __init__(self) -> None:
"""Initialize mock HTTP client with base URL and headers."""
self.base_url = "https://app.bloomgrowth.com/api/v1"
self.headers = {"Authorization": "Bearer test-token"}
class ConcreteOperations(AbstractOperations):
"""Concrete implementation for testing."""
@property
def user_id(self) -> int:
"""Get the current user's ID."""
if self._user_id is None:
self._user_id = 123
return self._user_id
@user_id.setter
def user_id(self, value: int) -> None:
"""Set the user ID."""
self._user_id = value
class TestAbstractOperations:
"""Test cases for AbstractOperations."""
def test_init(self) -> None:
"""Test initialization of abstract operations."""
client = MockHTTPClient()
ops = ConcreteOperations(client)
assert ops._client == client
assert ops._user_id is None
def test_user_id_property(self) -> None:
"""Test user_id property getter and setter."""
client = MockHTTPClient()
ops = ConcreteOperations(client)
# Test getter with default
assert ops.user_id == 123
assert ops._user_id == 123 # Should be cached
# Test setter
ops.user_id = 456
assert ops.user_id == 456
assert ops._user_id == 456
def test_validate_mutual_exclusion(self) -> None:
"""Test mutual exclusion validation."""
client = MockHTTPClient()
ops = ConcreteOperations(client)
# Should not raise when only one param is provided
ops._validate_mutual_exclusion(1, None, "param1", "param2")
ops._validate_mutual_exclusion(None, 2, "param1", "param2")
ops._validate_mutual_exclusion(None, None, "param1", "param2")
# Should raise when both params are provided
with pytest.raises(ValueError, match="Cannot specify both param1 and param2"):
ops._validate_mutual_exclusion(1, 2, "param1", "param2")
def test_prepare_params(self) -> None:
"""Test prepare_params method."""
client = MockHTTPClient()
ops = ConcreteOperations(client)
# Test with None values
params = ops._prepare_params(a=1, b=None, c="test", d=None)
assert params == {"a": 1, "c": "test"}
# Test with no None values
params = ops._prepare_params(x=1, y=2, z=3)
assert params == {"x": 1, "y": 2, "z": 3}
# Test with all None values
params = ops._prepare_params(a=None, b=None)
assert params == {}
def test_process_bulk_sync_create_func_signature(self) -> None:
"""_process_bulk_sync accepts Callable[[dict[str, Any]], T] create_func."""
client = MockHTTPClient()
ops = ConcreteOperations(client)
def create_func(item_data: dict) -> str:
return f"created-{item_data['title']}"
result = ops._process_bulk_sync(
[
{"title": "a"},
{"title": "b"},
{}, # missing required field
],
create_func,
required_fields=["title"],
)
assert result.successful == ["created-a", "created-b"]
assert len(result.failed) == 1
assert result.failed[0].index == 2
assert "title" in result.failed[0].error