e-data 2.0.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,83 @@
1
+ """Tests for MaximeterService."""
2
+
3
+ from datetime import datetime
4
+ from unittest.mock import AsyncMock, Mock, patch
5
+
6
+ import pytest
7
+ import pytest_asyncio
8
+
9
+ from edata.models.database import MaxPowerModel
10
+ from edata.services.maximeter import MaximeterService
11
+
12
+
13
+ @pytest_asyncio.fixture
14
+ async def maximeter_service():
15
+ """Create a maximeter service with mocked dependencies."""
16
+ with patch("edata.services.maximeter.get_database_service") as mock_db_factory:
17
+ mock_db = Mock()
18
+ # Hacer que los métodos de la base de datos retornen AsyncMock
19
+ mock_db.get_maxpower = AsyncMock(return_value=[])
20
+ mock_db.save_maxpower = AsyncMock(return_value=Mock())
21
+ mock_db_factory.return_value = mock_db
22
+
23
+ # Create a mock DatadisConnector
24
+ mock_datadis_connector = Mock()
25
+ service = MaximeterService(datadis_connector=mock_datadis_connector)
26
+ service._db_service = mock_db
27
+ return service
28
+
29
+
30
+ @pytest.fixture
31
+ def sample_maximeter():
32
+ """Sample maximeter data for testing."""
33
+ return [
34
+ MaxPowerModel(
35
+ cups="ES001234567890123456AB",
36
+ datetime=datetime(2023, 1, 15, 14, 30),
37
+ value_kw=2.5,
38
+ ),
39
+ MaxPowerModel(
40
+ cups="ES001234567890123456AB",
41
+ datetime=datetime(2023, 2, 20, 16, 45),
42
+ value_kw=3.2,
43
+ ),
44
+ MaxPowerModel(
45
+ cups="ES001234567890123456AB",
46
+ datetime=datetime(2023, 3, 10, 12, 15),
47
+ value_kw=1.8,
48
+ ),
49
+ ]
50
+
51
+
52
+ class TestMaximeterService:
53
+ """Test class for MaximeterService."""
54
+
55
+ @pytest.mark.asyncio
56
+ async def test_get_maximeter_summary(self, maximeter_service, sample_maximeter):
57
+ """Test getting maximeter summary."""
58
+ # Setup mocks
59
+ maximeter_service.get_stored_maxpower = AsyncMock(return_value=sample_maximeter)
60
+
61
+ # Execute
62
+ result = await maximeter_service.get_maximeter_summary("ES001234567890123456AB")
63
+
64
+ # Verify
65
+ assert result["max_power_kW"] == 3.2 # max value
66
+ assert result["max_power_date"] == datetime(2023, 2, 20, 16, 45)
67
+ assert result["max_power_mean_kW"] == 2.5 # (2.5 + 3.2 + 1.8) / 3
68
+ assert result["max_power_90perc_kW"] == 3.2 # 90th percentile
69
+
70
+ @pytest.mark.asyncio
71
+ async def test_get_maximeter_summary_no_data(self, maximeter_service):
72
+ """Test getting maximeter summary with no data."""
73
+ # Setup mocks
74
+ maximeter_service.get_stored_maxpower = AsyncMock(return_value=[])
75
+
76
+ # Execute
77
+ result = await maximeter_service.get_maximeter_summary("ES001234567890123456AB")
78
+
79
+ # Verify
80
+ assert result["max_power_kW"] is None
81
+ assert result["max_power_date"] is None
82
+ assert result["max_power_mean_kW"] is None
83
+ assert result["max_power_90perc_kW"] is None
@@ -0,0 +1,251 @@
1
+ """Tests for SupplyService."""
2
+
3
+ from datetime import datetime
4
+ from unittest.mock import AsyncMock, Mock, patch
5
+
6
+ import pytest
7
+ import pytest_asyncio
8
+
9
+ from edata.models.database import SupplyModel
10
+ from edata.services.supply import SupplyService
11
+
12
+
13
+ @pytest_asyncio.fixture
14
+ async def supply_service():
15
+ """Create a supply service with mocked dependencies."""
16
+ with patch("edata.services.supply.get_database_service") as mock_db_factory:
17
+ mock_db = Mock()
18
+ # Hacer que los métodos de la base de datos retornen AsyncMock
19
+ mock_db.get_supplies = AsyncMock(return_value=[])
20
+ mock_db.save_supply = AsyncMock(return_value=Mock())
21
+ mock_db_factory.return_value = mock_db
22
+
23
+ # Create a mock DatadisConnector
24
+ mock_datadis_connector = Mock()
25
+ service = SupplyService(datadis_connector=mock_datadis_connector)
26
+ service._db_service = mock_db
27
+ return service
28
+
29
+
30
+ @pytest.fixture
31
+ def sample_supplies():
32
+ """Sample supply data for testing."""
33
+ return [
34
+ SupplyModel(
35
+ cups="ES001234567890123456AB",
36
+ distributor_code="123",
37
+ point_type=5,
38
+ date_start=datetime(2023, 1, 1),
39
+ date_end=datetime(2024, 12, 31),
40
+ address="Test Address 1",
41
+ postal_code="12345",
42
+ province="Test Province 1",
43
+ municipality="Test Municipality 1",
44
+ distributor="Test Distributor 1",
45
+ ),
46
+ SupplyModel(
47
+ cups="ES987654321098765432BA",
48
+ distributor_code="456",
49
+ point_type=4,
50
+ date_start=datetime(2023, 6, 1),
51
+ date_end=datetime(2025, 6, 1),
52
+ address="Test Address 2",
53
+ postal_code="67890",
54
+ province="Test Province 2",
55
+ municipality="Test Municipality 2",
56
+ distributor="Test Distributor 2",
57
+ ),
58
+ ]
59
+
60
+
61
+ class TestSupplyService:
62
+ """Test class for SupplyService."""
63
+
64
+ @pytest.mark.asyncio
65
+ async def test_update_supplies_success(self, supply_service):
66
+ """Test successful supply update."""
67
+ # Setup mocks - now returns Pydantic models
68
+ supply_service._datadis.get_supplies = AsyncMock(
69
+ return_value=[
70
+ SupplyModel(
71
+ cups="ES001234567890123456AB",
72
+ distributor_code="123",
73
+ point_type=5,
74
+ date_start=datetime(2023, 1, 1),
75
+ date_end=datetime(2024, 12, 31),
76
+ address="Test Address",
77
+ postal_code="12345",
78
+ province="Test Province",
79
+ municipality="Test Municipality",
80
+ distributor="Test Distributor",
81
+ )
82
+ ]
83
+ )
84
+ supply_service._db_service.get_supplies.side_effect = [
85
+ [],
86
+ [Mock()],
87
+ ] # No existing, then 1 stored
88
+ supply_service._db_service.save_supply.return_value = Mock()
89
+
90
+ # Execute
91
+ result = await supply_service.update_supplies()
92
+
93
+ # Verify
94
+ assert result["success"] is True
95
+ assert result["stats"]["fetched"] == 1
96
+ assert result["stats"]["saved"] == 1
97
+ assert result["stats"]["updated"] == 0
98
+ supply_service._datadis.get_supplies.assert_called_once()
99
+ supply_service._db_service.save_supply.assert_called_once()
100
+
101
+ @pytest.mark.asyncio
102
+ async def test_get_supplies(self, supply_service, sample_supplies):
103
+ """Test getting supplies."""
104
+ # Setup mocks
105
+ supply_service._db_service.get_supplies.return_value = sample_supplies
106
+
107
+ # Execute
108
+ result = await supply_service.get_supplies()
109
+
110
+ # Verify
111
+ assert len(result) == 2
112
+ assert result[0].cups == "ES001234567890123456AB"
113
+ assert result[1].cups == "ES987654321098765432BA"
114
+ supply_service._db_service.get_supplies.assert_called_once_with(cups=None)
115
+
116
+ @pytest.mark.asyncio
117
+ async def test_get_supply_by_cups(self, supply_service, sample_supplies):
118
+ """Test getting supply by CUPS."""
119
+ # Setup mocks
120
+ supply_service._db_service.get_supplies.return_value = [sample_supplies[0]]
121
+
122
+ # Execute
123
+ result = await supply_service.get_supply_by_cups("ES001234567890123456AB")
124
+
125
+ # Verify
126
+ assert result is not None
127
+ assert result.cups == "ES001234567890123456AB"
128
+ assert result.distributor == "Test Distributor 1"
129
+ supply_service._db_service.get_supplies.assert_called_once_with(
130
+ cups="ES001234567890123456AB"
131
+ )
132
+
133
+ @pytest.mark.asyncio
134
+ async def test_get_cups_list(self, supply_service, sample_supplies):
135
+ """Test getting CUPS list."""
136
+ # Setup mocks
137
+ supply_service._db_service.get_supplies.return_value = sample_supplies
138
+
139
+ # Execute
140
+ result = await supply_service.get_cups_list()
141
+
142
+ # Verify
143
+ assert len(result) == 2
144
+ assert "ES001234567890123456AB" in result
145
+ assert "ES987654321098765432BA" in result
146
+
147
+ @pytest.mark.asyncio
148
+ async def test_get_active_supplies(self, supply_service, sample_supplies):
149
+ """Test getting active supplies."""
150
+ # Setup mocks
151
+ supply_service._db_service.get_supplies.return_value = sample_supplies
152
+
153
+ # Execute - test with date in 2024 (both should be active)
154
+ result = await supply_service.get_active_supplies(datetime(2024, 6, 15))
155
+
156
+ # Verify
157
+ assert len(result) == 2 # Both supplies should be active in 2024
158
+ for supply in result:
159
+ assert supply.date_start <= datetime(2024, 6, 15) <= supply.date_end
160
+
161
+ @pytest.mark.asyncio
162
+ async def test_get_supply_stats(self, supply_service, sample_supplies):
163
+ """Test getting supply statistics."""
164
+ # Setup mocks
165
+ supply_service._db_service.get_supplies.return_value = sample_supplies
166
+
167
+ # Execute
168
+ result = await supply_service.get_supply_stats()
169
+
170
+ # Verify
171
+ # Verify
172
+ assert result["total_supplies"] == 2
173
+ assert result["total_cups"] == 2
174
+ assert result["date_range"]["earliest_start"] == datetime(2023, 1, 1)
175
+ assert result["date_range"]["latest_end"] == datetime(2025, 6, 1)
176
+ assert result["point_types"] == {5: 1, 4: 1}
177
+ assert result["distributors"] == {
178
+ "Test Distributor 1": 1,
179
+ "Test Distributor 2": 1,
180
+ }
181
+
182
+ @pytest.mark.asyncio
183
+ async def test_validate_cups(self, supply_service, sample_supplies):
184
+ """Test CUPS validation."""
185
+ # Setup mocks
186
+ supply_service._db_service.get_supplies.return_value = [sample_supplies[0]]
187
+
188
+ # Execute
189
+ result = await supply_service.validate_cups("ES001234567890123456AB")
190
+
191
+ # Verify
192
+ assert result is True
193
+
194
+ # Test invalid CUPS
195
+ supply_service._db_service.get_supplies.return_value = []
196
+ result = await supply_service.validate_cups("INVALID_CUPS")
197
+ assert result is False
198
+
199
+ @pytest.mark.asyncio
200
+ async def test_get_distributor_code(self, supply_service, sample_supplies):
201
+ """Test getting distributor code."""
202
+ # Setup mocks
203
+ supply_service._db_service.get_supplies.return_value = [sample_supplies[0]]
204
+
205
+ # Execute
206
+ result = await supply_service.get_distributor_code("ES001234567890123456AB")
207
+
208
+ # Verify
209
+ assert result == "123"
210
+
211
+ @pytest.mark.asyncio
212
+ async def test_get_point_type(self, supply_service, sample_supplies):
213
+ """Test getting point type."""
214
+ # Setup mocks
215
+ supply_service._db_service.get_supplies.return_value = [sample_supplies[0]]
216
+
217
+ # Execute
218
+ result = await supply_service.get_point_type("ES001234567890123456AB")
219
+
220
+ # Verify
221
+ assert result == 5
222
+
223
+ @pytest.mark.asyncio
224
+ async def test_update_supplies_no_data(self, supply_service):
225
+ """Test supply update with no data returned."""
226
+ # Setup mocks
227
+ supply_service._datadis.get_supplies = AsyncMock(return_value=[])
228
+
229
+ # Execute
230
+ result = await supply_service.update_supplies()
231
+
232
+ # Verify
233
+ assert result["success"] is True
234
+ assert result["stats"]["fetched"] == 0
235
+ assert result["stats"]["saved"] == 0
236
+
237
+ @pytest.mark.asyncio
238
+ async def test_update_supplies_error(self, supply_service):
239
+ """Test supply update with error."""
240
+ # Setup mocks
241
+ supply_service._datadis.get_supplies = AsyncMock(
242
+ side_effect=Exception("API Error")
243
+ )
244
+
245
+ # Execute
246
+ result = await supply_service.update_supplies()
247
+
248
+ # Verify
249
+ assert result["success"] is False
250
+ assert "error" in result
251
+ assert result["error"] == "API Error"