Files
elprisenligenu/tests/integration/test_integration.py
T
Brian Bjarke Jensen 1676fd10c9
Python Code Quality / python-code-quality (push) Successful in 15s
Test Python Package / test (push) Failing after 16s
initial commit
2025-10-30 00:00:02 +01:00

153 lines
5.6 KiB
Python

"""Integration tests for the elprisenligenu module."""
from datetime import datetime
from zoneinfo import ZoneInfo
import pytest
from elprisenligenu.api import API
from elprisenligenu.dto.hour_data import HourData
class TestElprisenLigenIntegration:
"""Integration tests that make real API calls."""
def setup_method(self) -> None:
"""Set up test fixtures before each test method."""
self.api = API()
self.tz = ZoneInfo("Europe/Copenhagen")
@pytest.mark.integration
def test_get_current_prices_dk1(self) -> None:
"""Test fetching current day prices for DK1 (integration test)."""
# Act
result = self.api.get_daily_prices(zone="DK1")
# Assert
assert isinstance(result, list)
assert all(isinstance(item, HourData) for item in result)
if result: # If data is available
first_hour = result[0]
assert isinstance(first_hour.DKK_per_kWh, float)
assert isinstance(first_hour.EUR_per_kWh, float)
assert isinstance(first_hour.EXR, float)
assert isinstance(first_hour.time_start, datetime)
assert isinstance(first_hour.time_end, datetime)
# Basic sanity checks
assert first_hour.EXR > 0 # Exchange rate should be positive
assert first_hour.time_start < first_hour.time_end
@pytest.mark.integration
def test_get_current_prices_dk2(self) -> None:
"""Test fetching current day prices for DK2 (integration test)."""
# Act
result = self.api.get_daily_prices(zone="DK2")
# Assert
assert isinstance(result, list)
assert all(isinstance(item, HourData) for item in result)
if result: # If data is available
first_hour = result[0]
assert isinstance(first_hour.DKK_per_kWh, float)
assert isinstance(first_hour.EUR_per_kWh, float)
assert isinstance(first_hour.EXR, float)
assert isinstance(first_hour.time_start, datetime)
assert isinstance(first_hour.time_end, datetime)
@pytest.mark.integration
def test_get_historical_prices(self) -> None:
"""Test fetching historical prices (integration test)."""
# Arrange - Use a date that should have data (not too far back)
historical_date = datetime(2024, 10, 1, tzinfo=self.tz)
# Act
result = self.api.get_daily_prices(zone="DK1", date=historical_date)
# Assert
assert isinstance(result, list)
if result: # If historical data is available
assert len(result) <= 24 # Should be max 24 hours
assert all(isinstance(item, HourData) for item in result)
# Check that all times are from the requested date
for hour_data in result:
assert hour_data.time_start.date() == historical_date.date()
@pytest.mark.integration
def test_price_consistency(self) -> None:
"""Test that EUR and DKK prices are consistent with exchange rate."""
# Act
result = self.api.get_daily_prices(zone="DK1")
# Assert
if result:
for hour_data in result:
# Calculate expected DKK price from EUR price and exchange rate
expected_dkk = hour_data.EUR_per_kWh * hour_data.EXR
# Allow for small floating point differences
difference = abs(hour_data.DKK_per_kWh - expected_dkk)
assert difference < 0.001, (
f"Price inconsistency: DKK={hour_data.DKK_per_kWh}, "
f"EUR={hour_data.EUR_per_kWh}, EXR={hour_data.EXR}, "
f"Expected DKK={expected_dkk}"
)
@pytest.mark.integration
def test_time_ordering(self) -> None:
"""Test that hours are returned in chronological order."""
# Act
result = self.api.get_daily_prices(zone="DK1")
# Assert
if len(result) > 1:
for i in range(1, len(result)):
assert result[i - 1].time_start <= result[i].time_start, (
f"Hours not in chronological order: "
f"{result[i - 1].time_start} > {result[i].time_start}"
)
@pytest.mark.integration
def test_hour_duration(self) -> None:
"""Test that each hour period is exactly 1 hour long."""
# Act
result = self.api.get_daily_prices(zone="DK1")
# Assert
if result:
for hour_data in result:
duration = hour_data.time_end - hour_data.time_start
assert duration.total_seconds() == 3600, (
f"Hour duration is not 1 hour: {duration}"
)
@pytest.mark.integration
def test_both_zones_same_day(self) -> None:
"""Test that both zones return data for the same day."""
# Arrange
test_date = datetime(2024, 10, 15, tzinfo=self.tz)
# Act
dk1_result = self.api.get_daily_prices(zone="DK1", date=test_date)
dk2_result = self.api.get_daily_prices(zone="DK2", date=test_date)
# Assert
# Both zones should have data for the same day
if dk1_result and dk2_result:
assert len(dk1_result) == len(dk2_result)
# Times should be the same
for dk1_hour, dk2_hour in zip(dk1_result, dk2_result):
assert dk1_hour.time_start == dk2_hour.time_start
assert dk1_hour.time_end == dk2_hour.time_end
# Exchange rates should be the same
assert dk1_hour.EXR == dk2_hour.EXR
# But prices can be different between zones
# (That's the whole point of having two zones!)